/** @file * @author Edouard DUPIN * @copyright 2011, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ ******************************************* ** IS REMOVED ******************************************* #include #include #include #include #include const etk::String& ege::ElementPhysic::getType() const { static const etk::String nameType("----"); return nameType; } ege::ElementPhysic::ElementPhysic(const ememory::SharedPtr& _env, bool _autoRigidBody) ://, float _mass) : ege::Element(_env), m_body(null), //m_shape(null), m_elementInPhysicsSystem(false), m_IA(null), m_detectCollisionEnable(false) { if (_autoRigidBody == true) { createRigidBody(); } else { EGE_TODO("add basic API to create custum rigid body"); } } ege::ElementPhysic::~ElementPhysic() { // in every case remove IA //iaDisable(); // same ... //dynamicDisable(); //removeShape(); // Destroy the rigid body //m_dynamicsWorld->destroyRigidBody(m_body); m_body = null; } void ege::ElementPhysic::createRigidBody(float _mass, bool _static) { // Initial position and orientation of the rigid body rp3d::Vector3 initPosition(0.0, 3.0, 0.0); rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); rp3d::Transform transform(initPosition, initOrientation); // Create a rigid body in the world m_body = null;//m_dynamicsWorld->createRigidBody(transform); /* if (_static = true) { m_body->setType(STATIC); //m_body->setType(KINEMATIC); // Disable gravity for this body m_body->enableGravity(false); } else { m_body->setType(DYNAMIC); } */ } bool ege::ElementPhysic::setMesh(ememory::SharedPtr _mesh) { EGE_WARNING("Set Mesh"); if (m_mesh != null) { //removeShape(); } ege::Element::setMesh(_mesh); // auto load the shape: if (m_mesh == null) { return true; } /* if (m_mesh->getShape() != null) { EGE_WARNING("create shape whith mesh internal shape ..."); m_shape = static_cast(m_mesh->getShape()); return true; } EGE_DEBUG("create the mesh shape with the mesh"); m_mesh->setShape(ege::collision::createShape(m_mesh)); EGE_DEBUG("set remove function shape"); m_mesh->setFreeShapeFunction(&FunctionFreeShape); m_shape = static_cast(m_mesh->getShape()); vec3 localInertia(0,0,0); m_shape->calculateLocalInertia(50000000, localInertia); // TODO : BETTER /// */ return true; } /* bool ege::ElementPhysic::setShape(btCollisionShape* _shape) { EGE_DEBUG("Set Shape"); removeShape(); m_shape = _shape; if (_shape == null) { EGE_WARNING("Remove shape ..."); } else { EGE_INFO("set shape ..."); } return true; } void ege::ElementPhysic::removeShape() { // no shape if (m_shape == null) { return; } // need to chek if the shape is the same as the mesh shape ... if (m_mesh == null) { // no mesh == > standalone shape ETK_DELETE(btCollisionShape, m_shape); m_shape=null; EGE_WARNING("Remove shape .2."); return; } if (m_shape != m_mesh->getShape()) { ETK_DELETE(btCollisionShape, m_shape); m_shape=null; EGE_WARNING("Remove shape .3."); return; } // otherwise : the shape is auto remove by the resources when no more needed ... } void ege::ElementPhysic::FunctionFreeShape(void* _pointer) { if (_pointer == null) { return; } ETK_DELETE(btCollisionShape, _pointer); } */ void ege::ElementPhysic::setPosition(const vec3& _pos) { if (m_body != null) { /* btTransform transformation = m_body->getCenterOfMassTransform(); transformation.setOrigin(_pos); m_body->setCenterOfMassTransform(transformation); */ } } const vec3& ege::ElementPhysic::getPosition() { /* if (m_body != null) { return m_body->getCenterOfMassPosition(); } */ return ege::Element::getPosition(); }; const vec3& ege::ElementPhysic::getSpeed() { static vec3 emptySpeed(0,0,0); /* if (m_body != null) { return m_body->getLinearVelocity(); } */ return emptySpeed; }; const float ege::ElementPhysic::getInvMass() { /* if (m_body != null) { return m_body->getInvMass(); } */ return 0.0000000001f; }; void ege::ElementPhysic::drawShape(/*const btCollisionShape* _shape,*/ ememory::SharedPtr _draw, mat4 _transformationMatrix, etk::Vector _tmpVertices) { #if 0 if( _draw == null || _shape == null) { return; } etk::Color tmpColor(1.0, 0.0, 0.0, 0.3); //EGE_DEBUG(" draw (6): !btIDebugDraw::DBG_DrawWireframe"); int shapetype=_shape->getShapeType(); switch (shapetype) { case SPHERE_SHAPE_PROXYTYPE: { // Sphere collision shape ... EGE_DEBUG(" draw (01): SPHERE_SHAPE_PROXYTYPE"); const btSphereShape* sphereShape = static_cast(_shape); float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin _draw->drawSphere(radius, 10, 10, _transformationMatrix, tmpColor); break; } case BOX_SHAPE_PROXYTYPE: { // Box collision shape ... EGE_DEBUG(" draw (02): BOX_SHAPE_PROXYTYPE"); const btBoxShape* boxShape = static_cast(_shape); vec3 halfExtent = boxShape->getHalfExtentsWithMargin(); _draw->drawSquare(halfExtent, _transformationMatrix, tmpColor); break; } case CONE_SHAPE_PROXYTYPE: { // Cone collision shape ... EGE_DEBUG(" draw (03): CONE_SHAPE_PROXYTYPE"); break; } case CAPSULE_SHAPE_PROXYTYPE: { // Capsule collision shape ... EGE_DEBUG(" draw (04): CAPSULE_SHAPE_PROXYTYPE"); break; } case CYLINDER_SHAPE_PROXYTYPE: { // Cylinder collision shape ... EGE_DEBUG(" draw (05): CYLINDER_SHAPE_PROXYTYPE"); break; } case CONVEX_HULL_SHAPE_PROXYTYPE: { // Convex Hull collision shape ... EGE_DEBUG(" draw (06): CONVEX_HULL_SHAPE_PROXYTYPE"); if (_shape->isConvex()) { EGE_DEBUG(" shape->isConvex()"); const btConvexPolyhedron* poly = _shape->isPolyhedral() ? ((btPolyhedralConvexShape*) _shape)->getConvexPolyhedron() : 0; if (null!=poly) { EGE_DEBUG(" have poly"); /* glBegin(GL_TRIANGLES); for (int32_t iii=0 ; iiim_faces.size() ; iii++) { btVector3 centroid(0,0,0); int numVerts = poly->m_faces[iii].m_indices.size(); if (numVerts>2) { btVector3 v1 = poly->m_vertices[poly->m_faces[iii].m_indices[0]]; for (int32_t vvv=0;vvvm_faces[iii].m_indices.size()-2;vvv++) { btVector3 v2 = poly->m_vertices[poly->m_faces[iii].m_indices[vvv+1]]; btVector3 v3 = poly->m_vertices[poly->m_faces[iii].m_indices[vvv+2]]; btVector3 normal = (v3-v1).cross(v2-v1); normal.normalize (); glNormal3f(normal.getX(),normal.getY(),normal.getZ()); glVertex3f (v1.x(), v1.y(), v1.z()); glVertex3f (v2.x(), v2.y(), v2.z()); glVertex3f (v3.x(), v3.y(), v3.z()); } } } glEnd(); */ } else { // TODO : set it back ... /* ShapeCache* sc=cache((btConvexShape*)_shape); //glutSolidCube(1.0); btShapeHull* hull = &sc->m_shapehull; if (hull->numTriangles () > 0) { int index = 0; const unsigned int* idx = hull->getIndexPointer(); const btVector3* vtx = hull->getVertexPointer(); glBegin (GL_TRIANGLES); for (int i = 0; i < hull->numTriangles(); i++) { int i1 = index++; int i2 = index++; int i3 = index++; btAssert(i1 < hull->numIndices() && i2 < hull->numIndices() && i3 < hull->numIndices()); int index1 = idx[i1]; int index2 = idx[i2]; int index3 = idx[i3]; btAssert(index1 < hull->numVertices() && index2 < hull->numVertices() && index3 < hull->numVertices()); btVector3 v1 = vtx[index1]; btVector3 v2 = vtx[index2]; btVector3 v3 = vtx[index3]; btVector3 normal = (v3-v1).cross(v2-v1); normal.normalize(); glNormal3f(normal.getX(),normal.getY(),normal.getZ()); glVertex3f (v1.x(), v1.y(), v1.z()); glVertex3f (v2.x(), v2.y(), v2.z()); glVertex3f (v3.x(), v3.y(), v3.z()); } glEnd (); } */ } } else { EGE_DEBUG(" !!! shape is NOT Convex() !!!"); } break; } case COMPOUND_SHAPE_PROXYTYPE: { // Multiple sub element collision shape ... EGE_DEBUG(" draw (07): COMPOUND_SHAPE_PROXYTYPE"); const btCompoundShape* compoundShape = static_cast(_shape); for (int32_t iii=compoundShape->getNumChildShapes()-1;iii >= 0;iii--) { btTransform childTrans = compoundShape->getChildTransform(iii); const btCollisionShape* colShape = compoundShape->getChildShape(iii); btScalar mmm[16]; childTrans.getOpenGLMatrix(mmm); mat4 transformationMatrix(mmm); transformationMatrix.transpose(); transformationMatrix = _transformationMatrix * transformationMatrix; drawShape(colShape, _draw, transformationMatrix, _tmpVertices); } break; } case EMPTY_SHAPE_PROXYTYPE: { // No collision shape ... EGE_DEBUG(" draw (08): EMPTY_SHAPE_PROXYTYPE"); // nothing to display ... break; } default: { // must be done later ... EGE_DEBUG(" draw (09): default"); } } #endif } void ege::ElementPhysic::draw(int32_t _pass) { if (m_elementInPhysicsSystem == false) { return; } /* //EGE_INFO("draw : " << _pass ); if (_pass == 0) { if( m_body != null && m_mesh != null) { //EGE_INFO("element pos = " << getPosition()); float mmm[16]; // Get the interpolated transform of the rigid body rp3d::Transform transform = m_body->getInterpolatedTransform(); // Get the OpenGL matrix array of the transform transform.getOpenGLMatrix(matrix); //EGE_INFO(" mat = " << mat4(mmm)); mat4 transformationMatrix(mmm); //mat4 transformationMatrix = mat4(mmm) * etk::matScale(vec3(20,20,20)); // TODO: check this : transformationMatrix.transpose(); m_mesh->draw(transformationMatrix); } } */ } void ege::ElementPhysic::dynamicEnable() { if (m_elementInPhysicsSystem == true) { return; } if(m_body != null) { EGE_VERBOSE("dynamicEnable : RigidBody"); //m_env->getPhysicEngine().getDynamicWorld()->addRigidBody(m_body); } if(m_IA != null) { EGE_VERBOSE("dynamicEnable : IA"); //m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); } m_elementInPhysicsSystem = true; } void ege::ElementPhysic::dynamicDisable() { if (m_elementInPhysicsSystem == false) { return; } if(m_IA != null) { EGE_VERBOSE("dynamicDisable : IA"); //m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); } if(m_body != null) { EGE_VERBOSE("dynamicDisable : RigidBody"); // Unlink element from the engine //m_env->getPhysicEngine().getDynamicWorld()->removeRigidBody(m_body); //m_env->getPhysicEngine().getDynamicWorld()->removeCollisionObject(m_body); } m_elementInPhysicsSystem = false; } void ege::ElementPhysic::iaEnable() { if (m_IA != null) { // IA already started ... return; } m_IA = ETK_NEW(localIA, *this); if (m_IA == null) { EGE_ERROR("Can not start the IA == > allocation error"); return; } if (m_elementInPhysicsSystem == true) { //m_env->getPhysicEngine().getDynamicWorld()->addAction(m_IA); } } void ege::ElementPhysic::iaDisable() { if (m_IA == null) { // IA already stopped ... return; } if (m_elementInPhysicsSystem == true) { //m_env->getPhysicEngine().getDynamicWorld()->removeAction(m_IA); } // remove IA: ETK_DELETE(localIA, m_IA); m_IA = null; } void ege::ElementPhysic::setMass(float _value) { if (m_body == null) { return; } /* vec3 localInertia(0,0,0); if (_value != 0.0f && getShape()!=null) { //getShape()->calculateLocalInertia(_value, localInertia); EWOL_ERROR("Update inertia calculated : " << localInertia); } m_body->setMassProps(_value, localInertia); */ } void ege::ElementPhysic::setLinearVelocity(const vec3& _value) { if (m_body == null) { EGE_WARNING("no body"); return; } // Force vector (in Newton) rp3d::Vector3 force(_value.x(), _value.y(), _value.z()); // Apply a force to the center of the body m_body->applyForceToCenterOfMass(force); } void ege::ElementPhysic::setTorqueImpulse(const vec3& _value) { if (m_body == null) { EGE_WARNING("no body"); return; } // Torque vector rp3d::Vector3 torque(_value.x(), _value.y(), _value.z()); // Apply a torque to the body m_body->applyTorque(torque); } void ege::ElementPhysic::setAngularVelocity(const vec3& _value) { if (m_body == null) { EGE_WARNING("no body"); return; } //m_body->setAngularVelocity(_value); } /* btQuaternion ege::ElementPhysic::getOrientation() const { if (m_body == null) { EGE_WARNING("no body"); return btQuaternion(0,0,0,0); } //return m_body->getOrientation(); return btQuaternion(0,0,0,0); } */ void ege::ElementPhysic::setCollisionDetectionStatus(bool _status) { if (m_body == null) { EGE_WARNING("no body"); return; } /* if (m_detectCollisionEnable == _status) { return; } m_detectCollisionEnable = _status; if (m_detectCollisionEnable == true) { m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } else { if ((m_body->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) != 0) { m_body->setCollisionFlags(m_body->getCollisionFlags() - btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } } */ }