Path: blob/master/scene/resources/3d/capsule_shape_3d.cpp
9898 views
/**************************************************************************/1/* capsule_shape_3d.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "capsule_shape_3d.h"3132#include "scene/resources/3d/primitive_meshes.h"33#include "servers/physics_server_3d.h"3435Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() const {36float c_radius = get_radius();37float c_height = get_height();3839Vector<Vector3> points;4041Vector3 d(0, c_height * 0.5f - c_radius, 0);42for (int i = 0; i < 360; i++) {43float ra = Math::deg_to_rad((float)i);44float rb = Math::deg_to_rad((float)i + 1);45Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * c_radius;46Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * c_radius;4748points.push_back(Vector3(a.x, 0, a.y) + d);49points.push_back(Vector3(b.x, 0, b.y) + d);5051points.push_back(Vector3(a.x, 0, a.y) - d);52points.push_back(Vector3(b.x, 0, b.y) - d);5354if (i % 90 == 0) {55points.push_back(Vector3(a.x, 0, a.y) + d);56points.push_back(Vector3(a.x, 0, a.y) - d);57}5859Vector3 dud = i < 180 ? d : -d;6061points.push_back(Vector3(0, a.x, a.y) + dud);62points.push_back(Vector3(0, b.x, b.y) + dud);63points.push_back(Vector3(a.y, a.x, 0) + dud);64points.push_back(Vector3(b.y, b.x, 0) + dud);65}6667return points;68}6970Ref<ArrayMesh> CapsuleShape3D::get_debug_arraymesh_faces(const Color &p_modulate) const {71Array capsule_array;72capsule_array.resize(RS::ARRAY_MAX);73CapsuleMesh::create_mesh_array(capsule_array, radius, height, 32, 8);7475Vector<Color> colors;76const PackedVector3Array &verts = capsule_array[RS::ARRAY_VERTEX];77const int32_t verts_size = verts.size();78for (int i = 0; i < verts_size; i++) {79colors.append(p_modulate);80}8182Ref<ArrayMesh> capsule_mesh = memnew(ArrayMesh);83capsule_array[RS::ARRAY_COLOR] = colors;84capsule_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, capsule_array);85return capsule_mesh;86}8788real_t CapsuleShape3D::get_enclosing_radius() const {89return height * 0.5f;90}9192void CapsuleShape3D::_update_shape() {93Dictionary d;94d["radius"] = radius;95d["height"] = height;96PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);97Shape3D::_update_shape();98}99100void CapsuleShape3D::set_radius(float p_radius) {101ERR_FAIL_COND_MSG(p_radius < 0.0f, "CapsuleShape3D radius cannot be negative.");102radius = p_radius;103if (height < radius * 2.0f) {104height = radius * 2.0f;105}106_update_shape();107emit_changed();108}109110float CapsuleShape3D::get_radius() const {111return radius;112}113114void CapsuleShape3D::set_height(float p_height) {115ERR_FAIL_COND_MSG(p_height < 0.0f, "CapsuleShape3D height cannot be negative.");116height = p_height;117if (radius > height * 0.5f) {118radius = height * 0.5f;119}120_update_shape();121emit_changed();122}123124float CapsuleShape3D::get_height() const {125return height;126}127128void CapsuleShape3D::set_mid_height(real_t p_mid_height) {129ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "CapsuleShape3D mid-height cannot be negative.");130height = p_mid_height + radius * 2.0f;131_update_shape();132emit_changed();133}134135real_t CapsuleShape3D::get_mid_height() const {136return height - radius * 2.0f;137}138139void CapsuleShape3D::_bind_methods() {140ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape3D::set_radius);141ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape3D::get_radius);142ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape3D::set_height);143ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape3D::get_height);144ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleShape3D::set_mid_height);145ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleShape3D::get_mid_height);146147ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_radius", "get_radius");148ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_height", "get_height");149ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height");150ADD_LINKED_PROPERTY("radius", "height");151ADD_LINKED_PROPERTY("height", "radius");152}153154CapsuleShape3D::CapsuleShape3D() :155Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) {156_update_shape();157}158159160