void PhysicsBodyComponent::onInitialize() { if(! mNode->hasComponent(mMeshComponentName)) { Logger::get().error("Node " + mNode->getName() + " has no Component named " + mMeshComponentName + " which is required to create the" + " PhysicsBodyComponent " + mName); exit(1); } auto mesh_component = mNode->findComponent<MeshComponent>(mMeshComponentName); BtOgre::StaticMeshToShapeConverter converter(mesh_component->getOgreEntity()); // TODO: CollisionShapes should likely be stored at a central place. // Perhaps the PhysicsManager is a good place. It would save a lot of memory // for many bodies with the same CollisionShape. if(mCollisionShapeType == BOX) { Ogre::Vector3 size = mesh_component->getOgreEntity()->getBoundingBox().getSize(); size /= 2.0; mCollisionShape = new btBoxShape(BtOgre::Convert::toBullet(size)); //mCollisionShape = converter.createBox(); } else if(mCollisionShapeType == CONVEX) mCollisionShape = converter.createConvex(); else if(mCollisionShapeType == SPHERE) { mCollisionShape = new btSphereShape(mesh_component->getOgreEntity()->getBoundingRadius()); } else if(mCollisionShapeType == CYLINDER) { Ogre::Vector3 size = mesh_component->getOgreEntity()->getBoundingBox().getSize(); size /= 2.0; mCollisionShape = new btCylinderShape(BtOgre::Convert::toBullet(size)); } else if(mCollisionShapeType == TRIMESH) mCollisionShape = converter.createTrimesh(); mCollisionShape->setLocalScaling(BtOgre::Convert::toBullet(this->getNode()->getScale())); btVector3 inertia(0, 0, 0); //Only the rigidbody's mass doesn't equal to zero is dynamic or some odd phenomenon may appear. if(mMass != 0.0f) mCollisionShape->calculateLocalInertia(mMass, inertia); btDefaultMotionState* state = new btDefaultMotionState( btTransform(BtOgre::Convert::toBullet(getNode()->getRotation(Node::SCENE)), BtOgre::Convert::toBullet(getNode()->getPosition(Node::SCENE)))); //Here's the most tricky part. You need to give it 5.0 as its temporary mass. //Or you will find your player character keeps falling down no matter there's a ground. //Its real mass will be set in OnEnable(). mBody = new btRigidBody(5.0, state, mCollisionShape, inertia); std::cout << mCollisionShape->getLocalScaling().getY() << std::endl; // Store pointer to this PhysicsBodyComponent for later retrieval (for // collisions, for instance) mBody->setFriction(1.0); mBody->setUserPointer((void *)(this)); }
Node::NodeSP SceneLoader::__loadMesh(const QDomElement& og_component, Node::NodeSP dt_node) { Node::NodeSP node = dt_node; if ( !og_component.isNull() ) { QString name = og_component.attribute(SL_NAME); if ( node == nullptr ) { node = mScene->addChildNode(new Node(name + "_node")); QDomElement pos = og_component.firstChildElement(SL_POS); QDomElement rot = og_component.firstChildElement(SL_ROT); QDomElement scale = og_component.firstChildElement(SL_SCALE); node->setPosition(pos.attribute(SL_X).toFloat(), pos.attribute(SL_Y).toFloat(), pos.attribute(SL_Z).toFloat()); node->setRotation(Ogre::Quaternion(rot.attribute(SL_QW).toFloat(), rot.attribute(SL_QX).toFloat(), rot.attribute(SL_QY).toFloat(), rot.attribute(SL_QZ).toFloat())); node->setScale(Ogre::Vector3(scale.attribute(SL_X).toFloat(), scale.attribute(SL_Y).toFloat(), scale.attribute(SL_Z).toFloat())); } QDomElement unknown_mesh = og_component.firstChildElement(SL_SCALE).nextSiblingElement(); if ( unknown_mesh.nodeName() == SL_MESH_ENTITY ) { const QDomElement& entity = unknown_mesh; //add mesh component auto mesh = node->addComponent<MeshComponent>( new MeshComponent(entity.attribute(SL_MESH_HANDLE), "", entity.attribute(SL_NAME)) ); //set entity attributes for ( QDomElement mat = entity.firstChildElement(); !mat.isNull(); mat = mat.nextSiblingElement() ) { QString material_handle = mat.attribute(SL_MESH_ENTITY_MATERIAL_NAME); uint32_t index = mat.attribute(SL_MESH_ENTITY_INDEX).toUInt(); mesh->getOgreEntity()->getSubEntity(index)->setMaterialName(material_handle.toStdString()); } QString cast_shadows = entity.attribute(SL_CAST_SHADOWS); if ( cast_shadows == SL_TRUE ) { mesh->setCastShadows(true); } else if ( cast_shadows == SL_FALSE ) { mesh->setCastShadows(false); } mesh->enable(); } else if ( unknown_mesh.nodeName() == SL_MESH_PLANE ) { const QDomElement& plane = unknown_mesh; if ( !plane.isNull() ) { //create plane OgreProcedural::PlaneGenerator() .setSizeX(plane.attribute(SL_MESH_PLANE_SIZEX).toFloat()) .setSizeY(plane.attribute(SL_MESH_PLANE_SIZEY).toFloat()) .setEnableNormals(plane.attribute(SL_MESH_PLANE_ENABLE_NORMALS).toInt()) .setNumSegX(plane.attribute(SL_MESH_PLANE_SEGMENTSX).toInt()) .setNumSegY(plane.attribute(SL_MESH_PLANE_SEGMENTSY).toInt()) .setNumTexCoordSet(plane.attribute(SL_MESH_PLANE_NUMTEXCOORD).toInt()) .setUTile(plane.attribute(SL_MESH_PLANE_UTILE).toFloat()) .setVTile(plane.attribute(SL_MESH_PLANE_VTILE).toFloat()) .setNormal(Ogre::Vector3( plane.firstChildElement(SL_MESH_PLANE_NORMAL).attribute(SL_X).toFloat(), plane.firstChildElement(SL_MESH_PLANE_NORMAL).attribute(SL_Y).toFloat(), plane.firstChildElement(SL_MESH_PLANE_NORMAL).attribute(SL_Z).toFloat())) .realizeMesh(plane.attribute(SL_NAME).toStdString()); //add mesh component auto mesh = node->addComponent<MeshComponent>( new MeshComponent(plane.attribute(SL_NAME), plane.attribute(SL_MESH_PLANE_MATERIAL), plane.attribute(SL_NAME)) ); mesh->enable(); } } } return node; }