| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- /*
- Copyright (c) 2013 Daniele Bartolini, Michele Rossi
- Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "Actor.h"
- #include "Device.h"
- #include "Log.h"
- #include "Matrix4x4.h"
- #include "MeshResource.h"
- #include "PhysicsResource.h"
- #include "PxPhysicsAPI.h"
- #include "Quaternion.h"
- #include "ResourceManager.h"
- #include "SceneGraph.h"
- #include "Unit.h"
- #include "Vector3.h"
- #include "World.h"
- #include "PhysicsWorld.h"
- #include "PxCooking.h"
- #include "PxDefaultStreams.h"
- using physx::PxActorFlag;
- using physx::PxActorType;
- using physx::PxBoxGeometry;
- using physx::PxCapsuleGeometry;
- using physx::PxConvexFlag;
- using physx::PxConvexMesh;
- using physx::PxConvexMeshDesc;
- using physx::PxD6Axis;
- using physx::PxD6Joint;
- using physx::PxD6JointCreate;
- using physx::PxD6Motion;
- using physx::PxFilterData;
- using physx::PxForceMode;
- using physx::PxMat44;
- using physx::PxPlaneGeometry;
- using physx::PxReal;
- using physx::PxRigidActor;
- using physx::PxRigidBody;
- using physx::PxRigidBodyExt;
- using physx::PxRigidDynamic;
- using physx::PxRigidDynamicFlag;
- using physx::PxRigidStatic;
- using physx::PxShape;
- using physx::PxShapeFlag;
- using physx::PxSphereGeometry;
- using physx::PxTransform;
- using physx::PxU32;
- using physx::PxU16;
- using physx::PxVec3;
- using physx::PxDefaultMemoryOutputStream;
- using physx::PxDefaultMemoryInputData;
- using physx::PxConvexMeshGeometry;
- namespace crown
- {
- //-----------------------------------------------------------------------------
- Actor::Actor(PhysicsWorld& pw, const PhysicsResource* res, uint32_t actor_idx, SceneGraph& sg, int32_t node, UnitId unit_id)
- : m_world(pw)
- , m_resource(res)
- , m_index(actor_idx)
- , m_scene_graph(sg)
- , m_node(node)
- , m_unit(unit_id)
- {
- create_objects();
- }
- //-----------------------------------------------------------------------------
- Actor::~Actor()
- {
- destroy_objects();
- }
- //-----------------------------------------------------------------------------
- void Actor::create_objects()
- {
- const PhysicsActor& actor = m_resource->actor(m_index);
- PxScene* scene = m_world.physx_scene();
- PxPhysics* physics = m_world.physx_physics();
- const PhysicsConfigResource* config = m_world.resource();
- const PhysicsActor2& actor_class = config->actor(actor.actor_class);
- // Create rigid body
- const PxMat44 pose((PxReal*) (m_scene_graph.world_pose(m_node).to_float_ptr()));
- if (actor_class.flags & PhysicsActor2::DYNAMIC)
- {
- m_actor = physics->createRigidDynamic(PxTransform(pose));
- if (actor_class.flags & PhysicsActor2::KINEMATIC)
- {
- static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
- }
- PxD6Joint* joint = PxD6JointCreate(*physics, m_actor, PxTransform(pose), NULL, PxTransform(pose));
- joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
- joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
- joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
- }
- else
- {
- m_actor = physics->createRigidStatic(PxTransform(pose));
- }
- // Create shapes
- uint32_t shape_index = m_resource->shape_index(m_index);
- for (uint32_t i = 0; i < actor.num_shapes; i++)
- {
- const PhysicsShape& shape = m_resource->shape(shape_index);
- const PhysicsShape2& shape_class = config->shape(shape.shape_class);
- const PhysicsMaterial& material = config->material(shape.material);
- PxMaterial* mat = physics->createMaterial(material.static_friction, material.dynamic_friction, material.restitution);
- PxShape* px_shape = NULL;
- switch(shape.type)
- {
- case PhysicsShapeType::SPHERE:
- {
- px_shape = m_actor->createShape(PxSphereGeometry(shape.data_0), *mat);
- break;
- }
- case PhysicsShapeType::CAPSULE:
- {
- px_shape = m_actor->createShape(PxCapsuleGeometry(shape.data_0, shape.data_1), *mat);
- break;
- }
- case PhysicsShapeType::BOX:
- {
- px_shape = m_actor->createShape(PxBoxGeometry(shape.data_0, shape.data_1, shape.data_2), *mat);
- break;
- }
- case PhysicsShapeType::PLANE:
- {
- px_shape = m_actor->createShape(PxPlaneGeometry(), *mat);
- break;
- }
- case PhysicsShapeType::CONVEX_MESH:
- {
- MeshResource* resource = (MeshResource*) device()->resource_manager()->data(shape.resource);
- PxConvexMeshDesc convex_mesh_desc;
- convex_mesh_desc.points.count = resource->num_vertices();
- convex_mesh_desc.points.stride = sizeof(PxVec3);
- convex_mesh_desc.points.data = (PxVec3*) resource->vertices();
- convex_mesh_desc.triangles.count = resource->num_indices();
- convex_mesh_desc.triangles.stride = 3 * sizeof(PxU16);
- convex_mesh_desc.triangles.data = (PxU16*) resource->indices();
- convex_mesh_desc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
- convex_mesh_desc.vertexLimit = MAX_PHYSX_VERTICES;
- PxDefaultMemoryOutputStream buf;
- if(!m_world.physx_cooking()->cookConvexMesh(convex_mesh_desc, buf))
- CE_FATAL();
- PxDefaultMemoryInputData input(buf.getData(), buf.getSize());
- PxConvexMesh* convex_mesh = physics->createConvexMesh(input);
- px_shape = m_actor->createShape(PxConvexMeshGeometry(convex_mesh), *mat);
- break;
- }
- default:
- {
- CE_FATAL("Oops, unknown shape type");
- }
- }
- if (shape_class.trigger)
- {
- px_shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
- px_shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
- }
- shape_index++;
- }
- m_actor->userData = this;
- scene->addActor(*m_actor);
- }
- //-----------------------------------------------------------------------------
- void Actor::destroy_objects()
- {
- if (m_actor)
- {
- m_world.physx_scene()->removeActor(*m_actor);
- m_actor->release();
- }
- }
- //-----------------------------------------------------------------------------
- void Actor::enable_gravity()
- {
- m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
- }
- //-----------------------------------------------------------------------------
- void Actor::disable_gravity()
- {
- m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
- }
- //-----------------------------------------------------------------------------
- void Actor::enable_collision()
- {
- // PxFilterData filter_data;
- // filter_data.word0 = (PxU32) m_group;
- // filter_data.word1 = (PxU32) m_mask;
- // const PxU32 num_shapes = m_actor->getNbShapes();
- // PxShape** shapes = (PxShape**) default_allocator().allocate((sizeof(PxShape*) * num_shapes));
- // m_actor->getShapes(shapes, num_shapes);
- // for(PxU32 i = 0; i < num_shapes; i++)
- // {
- // PxShape* shape = shapes[i];
- // shape->setSimulationFilterData(filter_data);
- // }
- // default_allocator().deallocate(shapes);
- }
- //-----------------------------------------------------------------------------
- void Actor::disable_collision()
- {
- // PxFilterData filter_data;
- // filter_data.word0 = (PxU32) CollisionGroup::GROUP_0;
- // filter_data.word1 = (PxU32) CollisionGroup::GROUP_0;
- // const PxU32 num_shapes = m_actor->getNbShapes();
- // PxShape** shapes = (PxShape**) default_allocator().allocate((sizeof(PxShape*) * num_shapes));
- // m_actor->getShapes(shapes, num_shapes);
- // for(PxU32 i = 0; i < num_shapes; i++)
- // {
- // PxShape* shape = shapes[i];
- // shape->setSimulationFilterData(filter_data);
- // }
- // default_allocator().deallocate(shapes);
- }
- //-----------------------------------------------------------------------------
- void Actor::set_kinematic()
- {
- static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
- }
- //-----------------------------------------------------------------------------
- void Actor::clear_kinematic()
- {
- static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, false);
- m_scene_graph.set_world_pose(m_node, get_kinematic_pose());
- }
- //-----------------------------------------------------------------------------
- void Actor::move(const Vector3& pos)
- {
- CE_ASSERT(is_kinematic(), "Cannot call 'move' method for non-kinematic actor");
- PxVec3 position(pos.x, pos.y, pos.z);
- static_cast<PxRigidDynamic*>(m_actor)->setKinematicTarget(PxTransform(position));
- }
- //-----------------------------------------------------------------------------
- Matrix4x4 Actor::get_kinematic_pose() const
- {
- PxTransform transform;
- static_cast<PxRigidDynamic*>(m_actor)->getKinematicTarget(transform);
- Quaternion rot(transform.q.x, transform.q.y, transform.q.z, transform.q.w);
- Vector3 pos(transform.p.x, transform.p.y, transform.p.z);
-
- return Matrix4x4(rot, pos);
- }
- //-----------------------------------------------------------------------------
- bool Actor::is_static() const
- {
- return m_actor->getType() & PxActorType::eRIGID_STATIC;
- }
- //-----------------------------------------------------------------------------
- bool Actor::is_dynamic() const
- {
- return m_actor->getType() & PxActorType::eRIGID_DYNAMIC;
- }
- //-----------------------------------------------------------------------------
- bool Actor::is_kinematic() const
- {
- if (!is_dynamic()) return false;
- return static_cast<PxRigidDynamic*>(m_actor)->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC;
- }
- //-----------------------------------------------------------------------------
- float Actor::linear_damping() const
- {
- return ((PxRigidDynamic*)m_actor)->getLinearDamping();
- }
- //-----------------------------------------------------------------------------
- void Actor::set_linear_damping(float rate)
- {
- ((PxRigidDynamic*)m_actor)->setLinearDamping(rate);
- }
- //-----------------------------------------------------------------------------
- float Actor::angular_damping() const
- {
- return ((PxRigidDynamic*)m_actor)->getAngularDamping();
- }
- //-----------------------------------------------------------------------------
- void Actor::set_angular_damping(float rate)
- {
- ((PxRigidDynamic*)m_actor)->setAngularDamping(rate);
- }
- //-----------------------------------------------------------------------------
- Vector3 Actor::linear_velocity() const
- {
- PxVec3 vel = ((PxRigidBody*)m_actor)->getLinearVelocity();
- Vector3 velocity(vel.x, vel.y, vel.z);
- return velocity;
- }
- //-----------------------------------------------------------------------------
- void Actor::set_linear_velocity(const Vector3& vel)
- {
- PxVec3 velocity(vel.x, vel.y, vel.z);
- ((PxRigidBody*)m_actor)->setLinearVelocity(velocity);
- }
- //-----------------------------------------------------------------------------
- Vector3 Actor::angular_velocity() const
- {
- PxVec3 vel = ((PxRigidBody*)m_actor)->getAngularVelocity();
- Vector3 velocity(vel.x, vel.y, vel.z);
- return velocity;
- }
- //-----------------------------------------------------------------------------
- void Actor::set_angular_velocity(const Vector3& vel)
- {
- PxVec3 velocity(vel.x, vel.y, vel.z);
- ((PxRigidBody*)m_actor)->setAngularVelocity(velocity);
- }
- //-----------------------------------------------------------------------------
- void Actor::add_impulse(const Vector3& impulse)
- {
- Vector3 p = m_scene_graph.world_pose(m_node).translation();
- PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
- PxVec3(impulse.x, impulse.y, impulse.z),
- PxVec3(p.x, p.y, p.z),
- PxForceMode::eIMPULSE,
- true);
- }
- //-----------------------------------------------------------------------------
- void Actor::add_impulse_at(const Vector3& impulse, const Vector3& pos)
- {
- PxRigidBodyExt::addForceAtLocalPos(*static_cast<PxRigidDynamic*>(m_actor),
- PxVec3(impulse.x, impulse.y, impulse.z),
- PxVec3(pos.x, pos.y, pos.z),
- PxForceMode::eIMPULSE,
- true);
- }
- //-----------------------------------------------------------------------------
- void Actor::push(const Vector3& vel, const float mass)
- {
- // FIXME FIXME FIXME
- Vector3 p = m_scene_graph.world_pose(m_node).translation();
- Vector3 mq(vel.x * mass, vel.y * mass, vel.z * mass);
- Vector3 f(mq.x / 0.017, mq.y / 0.017, mq.z / 0.017);
- PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
- PxVec3(f.x, f.y, f.z),
- PxVec3(p.x, p.y, p.z));
- }
- //-----------------------------------------------------------------------------
- bool Actor::is_sleeping()
- {
- return ((PxRigidDynamic*)m_actor)->isSleeping();
- }
- //-----------------------------------------------------------------------------
- void Actor::wake_up()
- {
- ((PxRigidDynamic*)m_actor)->wakeUp();
- }
- //-----------------------------------------------------------------------------
- StringId32 Actor::name()
- {
- const PhysicsActor& a = m_resource->actor(m_index);
- return a.name;
- }
- //-----------------------------------------------------------------------------
- Unit* Actor::unit()
- {
- return (m_unit.id == INVALID_ID) ? NULL : m_world.world().lookup_unit(m_unit);
- }
- //-----------------------------------------------------------------------------
- void Actor::update(const Matrix4x4& pose)
- {
- m_scene_graph.set_world_pose(m_node, pose);
- }
- } // namespace crown
|