void Vehicle::Init() { // This function is called only from the main program when initially creating the vehicle, not on scene load ResourceCache* cache = GetSubsystem<ResourceCache>(); StaticModel* hullObject = node_->CreateComponent<StaticModel>(); hullBody_ = node_->CreateComponent<RigidBody>(); CollisionShape* hullShape = node_->CreateComponent<CollisionShape>(); node_->SetScale(Vector3(1.5f, 1.0f, 3.0f)); hullObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); hullObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); hullObject->SetCastShadows(true); hullShape->SetBox(Vector3::ONE); hullBody_->SetMass(4.0f); hullBody_->SetLinearDamping(0.2f); // Some air resistance hullBody_->SetAngularDamping(0.5f); hullBody_->SetCollisionLayer(1); InitWheel("FrontLeft", Vector3(-0.6f, -0.4f, 0.3f), frontLeft_, frontLeftID_); InitWheel("FrontRight", Vector3(0.6f, -0.4f, 0.3f), frontRight_, frontRightID_); InitWheel("RearLeft", Vector3(-0.6f, -0.4f, -0.3f), rearLeft_, rearLeftID_); InitWheel("RearRight", Vector3(0.6f, -0.4f, -0.3f), rearRight_, rearRightID_); GetWheelComponents(); }
heXoCam::heXoCam(Context *context, MasterControl *masterControl): Object(context), yaw_{0.0f}, pitch_{0.0f}, yawDelta_{0.0f}, pitchDelta_{0.0f}, forceMultiplier{1.0f} { masterControl_ = masterControl; SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(heXoCam, HandleSceneUpdate)); rootNode_ = masterControl_->world.scene->CreateChild("Camera"); Node* leftEye = rootNode_->CreateChild("Left Eye"); leftEye->SetPosition(Vector3::LEFT); stereoCam_.first_ = leftEye->CreateComponent<Camera>(); Node* rightEye = rootNode_->CreateChild("Right Eye"); rightEye->SetPosition(Vector3::RIGHT); stereoCam_.second_ = rightEye->CreateComponent<Camera>(); camera_ = rootNode_->CreateComponent<Camera>(); camera_->SetFarClip(128.0f); rootNode_->SetPosition(Vector3(0.0f, 42.0f, -23.0f)); rootNode_->SetRotation(Quaternion(65.0f, 0.0f, 0.0f)); rigidBody_ = rootNode_->CreateComponent<RigidBody>(); rigidBody_->SetAngularDamping(10.0f); CollisionShape* collisionShape = rootNode_->CreateComponent<CollisionShape>(); collisionShape->SetSphere(0.1f); rigidBody_->SetMass(1.0f); SetupViewport(); }
void Ragdolls::SpawnObject() { ResourceCache* cache = GetSubsystem<ResourceCache>(); Node* boxNode = scene_->CreateChild("Sphere"); boxNode->SetPosition(cameraNode_->GetPosition()); boxNode->SetRotation(cameraNode_->GetRotation()); boxNode->SetScale(0.25f); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml")); boxObject->SetCastShadows(true); RigidBody* body = boxNode->CreateComponent<RigidBody>(); body->SetMass(1.0f); body->SetRollingFriction(0.15f); CollisionShape* shape = boxNode->CreateComponent<CollisionShape>(); shape->SetSphere(1.0f); const float OBJECT_VELOCITY = 10.0f; // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component // to overcome gravity better body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY); }
void update_scene() { main_context::access(m_server, [&](main_context::Interface *imc) { Scene *scene = imc->check_scene(m_main_scene); Context *context = scene->GetContext(); ResourceCache *cache = context->GetSubsystem<ResourceCache>(); { Node *n = scene->GetChild("Base"); n->SetScale(Vector3(1.0f, 1.0f, 1.0f)); //n->SetPosition(Vector3(0.0f, 0.5f, 0.0f)); n->SetPosition(Vector3(0.0f, 0.5f, 0.0f)); //n->SetRotation(Quaternion(0, 90, 0)); int w = 10, h = 3, d = 10; ss_ data = "222222222211211111211111111111" "222222222211111111111111111111" "222222222211111111111111111111" "222222222211111111111111111111" "222222222211122111111112111111" "222233222211123111111112111111" "222233222211111111111111111111" "222222222211111111111111111111" "222222222211111111111111111111" "222222222211111111111111111111" ; // Convert data to the actually usable voxel type id namespace // starting from VOXELTYPEID_UNDEFINED=0 for(size_t i = 0; i < data.size(); i++){ data[i] = data[i] - '0'; } // Crude way of dynamically defining a voxel model n->SetVar(StringHash("simple_voxel_data"), Variant( PODVector<uint8_t>((const uint8_t*)data.c_str(), data.size()))); n->SetVar(StringHash("simple_voxel_w"), Variant(w)); n->SetVar(StringHash("simple_voxel_h"), Variant(h)); n->SetVar(StringHash("simple_voxel_d"), Variant(d)); // Load the same model in here and give it to the physics // subsystem so that it can be collided to SharedPtr<Model> model(interface::mesh:: create_8bit_voxel_physics_model(context, w, h, d, data, m_voxel_reg.get())); RigidBody *body = n->CreateComponent<RigidBody>(LOCAL); body->SetFriction(0.75f); CollisionShape *shape = n->CreateComponent<CollisionShape>( LOCAL); shape->SetTriangleMesh(model, 0, Vector3::ONE); } }); }
void SceneReplication::CreateScene() { scene_ = new Scene(context_); // Create scene content on the server only ResourceCache* cache = GetSubsystem<ResourceCache>(); // Create octree and physics world with default settings. Create them as local so that they are not needlessly replicated // when a client connects scene_->CreateComponent<Octree>(LOCAL); scene_->CreateComponent<PhysicsWorld>(LOCAL); // All static scene content and the camera are also created as local, so that they are unaffected by scene replication and are // not removed from the client upon connection. Create a Zone component first for ambient lighting & fog control. Node* zoneNode = scene_->CreateChild("Zone", LOCAL); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.1f, 0.1f, 0.1f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light without shadows Node* lightNode = scene_->CreateChild("DirectionalLight", LOCAL); lightNode->SetDirection(Vector3(0.5f, -1.0f, 0.5f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.2f, 0.2f, 0.2f)); light->SetSpecularIntensity(1.0f); // Create a "floor" consisting of several tiles. Make the tiles physical but leave small cracks between them for (int y = -20; y <= 20; ++y) { for (int x = -20; x <= 20; ++x) { Node* floorNode = scene_->CreateChild("FloorTile", LOCAL); floorNode->SetPosition(Vector3(x * 20.2f, -0.5f, y * 20.2f)); floorNode->SetScale(Vector3(20.0f, 1.0f, 20.0f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); RigidBody* body = floorNode->CreateComponent<RigidBody>(); body->SetFriction(1.0f); CollisionShape* shape = floorNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); } } // Create the camera. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera", LOCAL); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); }
Bool testCollisionShapes(const CollisionShape& a, const CollisionShape& b) { U ai = static_cast<U>(a.getType()); U bi = static_cast<U>(b.getType()); ANKI_ASSERT(matrix[ai][bi] != nullptr && "Collision algorithm is missing"); ANKI_ASSERT(ai < COUNT && bi < COUNT && "Out of range"); return matrix[bi][ai](a, b); }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ PhysicsZone::pCollisionShape_type PhysicsZone::createCapsuleShape(float _radius, float _height) { CollisionShape* pRawPointer = new CollisionShape(); pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1)); pRawPointer->setShapePtr(new btCapsuleShape(_radius, _height)); // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin) return pShape; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ PhysicsZone::pCollisionShape_type PhysicsZone::createBoxShape(float _dx, float _dy, float _dz) { CollisionShape* pRawPointer = new CollisionShape(); pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1)); pRawPointer->setShapePtr(new btBoxShape(btVector3(_dx,_dy,_dz))); // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin) return pShape; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ PhysicsZone::pCollisionShape_type PhysicsZone::createOvoidShape(float _radiusX, float _radiusY, float _radiusZ) { CollisionShape* pRawPointer = new CollisionShape(); pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1)); //seem to recall something about a multisphere shape being scalable in multiple directions... research further pRawPointer->setShapePtr(new btSphereShape(btScalar(_radiusX))); // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin) return pShape; }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ PhysicsZone::pCollisionShape_type PhysicsZone::createNullShape() { CollisionShape* pRawPointer = new CollisionShape(); pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1)); //bit of a hacktastic workaround, but see http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4461&hilit=btRigidBody+vs+btCollisionObject for intent pRawPointer->setShapePtr(new btSphereShape(btScalar(1.))); pRawPointer->setIsNUllShape(true); // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin) return pShape; }
void MeshInstance::create_convex_collision() { StaticBody *static_body = Object::cast_to<StaticBody>(create_convex_collision_node()); ERR_FAIL_COND(!static_body); static_body->set_name(String(get_name()) + "_col"); add_child(static_body); if (get_owner()) { CollisionShape *cshape = Object::cast_to<CollisionShape>(static_body->get_child(0)); static_body->set_owner(get_owner()); cshape->set_owner(get_owner()); } }
Node *MeshInstance::create_convex_collision_node() { if (mesh.is_null()) return NULL; Ref<Shape> shape = mesh->create_convex_shape(); if (shape.is_null()) return NULL; StaticBody *static_body = memnew(StaticBody); CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); static_body->add_child(cshape); return static_body; }
void CollisionShapeManager::SaveAllStoredShapesToBinaryFile(const String& FileName) { btDefaultSerializer* BulletSerializer = new btDefaultSerializer(1024*1024*5); BulletSerializer->startSerialization(); for( ShapeMapIterator it = this->CollisionShapes.begin() ; it != this->CollisionShapes.end() ; it++ ) { CollisionShape* Shape = (*it).second; BulletSerializer->registerNameForPointer((void*)Shape->_GetInternalShape(),(*it).first.c_str()); int len = Shape->_GetInternalShape()->calculateSerializeBufferSize(); btChunk* chunk = BulletSerializer->allocate(len,1); const char* structType = Shape->_GetInternalShape()->serialize(chunk->m_oldPtr, BulletSerializer); BulletSerializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,Shape->_GetInternalShape()); } BulletSerializer->finishSerialization(); FILE* f2 = fopen(FileName.c_str(),"wb"); fwrite(BulletSerializer->getBufferPointer(),BulletSerializer->getCurrentBufferSize(),1,f2); fclose(f2); }
Pickup::Pickup(Context *context, MasterControl *masterControl): SceneObject(context, masterControl), sinceLastPickup_{0.0f}, chaoInterval_{Random(23.0f, 100.0f)} { rootNode_->SetName("Pickup"); graphicsNode_ = rootNode_->CreateChild("Graphics"); model_ = graphicsNode_->CreateComponent<StaticModel>(); rootNode_->SetScale(0.8f); rootNode_->SetEnabledRecursive(false); rigidBody_ = rootNode_->CreateComponent<RigidBody>(); rigidBody_->SetRestitution(0.666f); rigidBody_->SetMass(0.666f); rigidBody_->SetLinearFactor(Vector3::ONE - Vector3::UP); rigidBody_->SetLinearDamping(0.5f); rigidBody_->SetFriction(0.0f); rigidBody_->SetAngularFactor(Vector3::UP); rigidBody_->SetAngularDamping(0.0f); rigidBody_->ApplyTorque(Vector3::UP * 32.0f); rigidBody_->SetLinearRestThreshold(0.0f); rigidBody_->SetAngularRestThreshold(0.0f); CollisionShape* collisionShape = rootNode_->CreateComponent<CollisionShape>(); collisionShape->SetSphere(1.5f); masterControl_->tileMaster_->AddToAffectors(WeakPtr<Node>(rootNode_), WeakPtr<RigidBody>(rigidBody_)); triggerNode_ = masterControl_->world.scene->CreateChild("PickupTrigger"); triggerBody_ = triggerNode_->CreateComponent<RigidBody>(); triggerBody_->SetTrigger(true); triggerBody_->SetMass(0.0f); triggerBody_->SetLinearFactor(Vector3::ZERO); CollisionShape* triggerShape = triggerNode_->CreateComponent<CollisionShape>(); triggerShape->SetSphere(2.5f); particleEmitter_ = graphicsNode_->CreateComponent<ParticleEmitter>(); particleEmitter_->SetEffect(masterControl_->cache_->GetTempResource<ParticleEffect>("Resources/Particles/Shine.xml")); SubscribeToEvent(triggerNode_, E_NODECOLLISIONSTART, URHO3D_HANDLER(Pickup, HandleTriggerStart)); SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(Pickup, HandleSceneUpdate)); }
/** * @param scaling The new local scaling vector */ inline void ProxyShape::setLocalScaling(const Vector3& scaling) { // Set the local scaling of the collision shape mCollisionShape->setLocalScaling(scaling); mBody->setIsSleeping(false); // Notify the body that the proxy shape has to be updated in the broad-phase mBody->updateProxyShapeInBroadPhase(this, true); }
void CharacterDemo::CreateCharacter() { ResourceCache* cache = GetSubsystem<ResourceCache>(); Node* objectNode = scene_->CreateChild("Jack"); objectNode->SetPosition(Vector3(0.0f, 1.0f, 0.0f)); // spin node Node* adjustNode = objectNode->CreateChild("AdjNode"); adjustNode->SetRotation( Quaternion(180, Vector3(0,1,0) ) ); // Create the rendering component + animation controller AnimatedModel* object = adjustNode->CreateComponent<AnimatedModel>(); object->SetModel(cache->GetResource<Model>("Models/Mutant/Mutant.mdl")); object->SetMaterial(cache->GetResource<Material>("Models/Mutant/Materials/mutant_M.xml")); object->SetCastShadows(true); adjustNode->CreateComponent<AnimationController>(); // Set the head bone for manual control object->GetSkeleton().GetBone("Mutant:Head")->animated_ = false; // Create rigidbody, and set non-zero mass so that the body becomes dynamic RigidBody* body = objectNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(1); body->SetMass(1.0f); // Set zero angular factor so that physics doesn't turn the character on its own. // Instead we will control the character yaw manually body->SetAngularFactor(Vector3::ZERO); // Set the rigidbody to signal collision also when in rest, so that we get ground collisions properly body->SetCollisionEventMode(COLLISION_ALWAYS); // Set a capsule shape for collision CollisionShape* shape = objectNode->CreateComponent<CollisionShape>(); shape->SetCapsule(0.7f, 1.8f, Vector3(0.0f, 0.9f, 0.0f)); // Create the character logic component, which takes care of steering the rigidbody // Remember it so that we can set the controls. Use a WeakPtr because the scene hierarchy already owns it // and keeps it alive as long as it's not removed from the hierarchy character_ = objectNode->CreateComponent<Character>(); }
void CollisionShapeManager::LoadAllShapesFromXMLFile(const String& FileName, const String& Group) { /// @todo Replace this stack allocated stream for one initialized from the Resource Manager, after the system is ready. Resource::FileStream ShapesStream( FileName, Resource::ResourceManager::GetSingletonPtr()->GetAssetPath(FileName,Group) ); XML::Document ShapesDoc; XML::ParseResult DocResult = ShapesDoc.Load(ShapesStream); if( DocResult.Status != XML::StatusOk ) { MEZZ_EXCEPTION(ExceptionBase::SYNTAX_ERROR_EXCEPTION_XML,"Failed to parse XML file \"" + FileName + "\"."); } XML::Node ShapesRoot = ShapesDoc.GetChild("InitializerRoot"); if( ShapesRoot.Empty() ) { MEZZ_EXCEPTION(ExceptionBase::SYNTAX_ERROR_EXCEPTION_XML,"Failed to find expected Root node in \"" + FileName + "\"."); } for( XML::NodeIterator ShapeIt = ShapesRoot.begin() ; ShapeIt != ShapesRoot.end() ; ++ShapeIt ) { CollisionShape* DeSerializedShape = Physics::CreateShape( (*ShapeIt) ); this->CollisionShapes.insert( std::pair<String,CollisionShape*>(DeSerializedShape->GetName(),DeSerializedShape) ); } }
//============================================================================== Bool Frustum::insideFrustum(const CollisionShape& b) const { update(); for(const Plane& plane : m_planesW) { if(b.testPlane(plane) < 0.0) { return false; } } return true; }
void Vehicle::InitWheel(const String& name, const Vector3& offset, WeakPtr<Node>& wheelNode, unsigned& wheelNodeID) { ResourceCache* cache = GetSubsystem<ResourceCache>(); // Note: do not parent the wheel to the hull scene node. Instead create it on the root level and let the physics // constraint keep it together wheelNode = GetScene()->CreateChild(name); wheelNode->SetPosition(node_->LocalToWorld(offset)); wheelNode->SetRotation(node_->GetRotation() * (offset.x_ >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f, 0.0f, 90.0f))); wheelNode->SetScale(Vector3(0.8f, 0.5f, 0.8f)); // Remember the ID for serialization wheelNodeID = wheelNode->GetID(); StaticModel* wheelObject = wheelNode->CreateComponent<StaticModel>(); RigidBody* wheelBody = wheelNode->CreateComponent<RigidBody>(); CollisionShape* wheelShape = wheelNode->CreateComponent<CollisionShape>(); Constraint* wheelConstraint = wheelNode->CreateComponent<Constraint>(); wheelObject->SetModel(cache->GetResource<Model>("Models/Cylinder.mdl")); wheelObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); wheelObject->SetCastShadows(true); wheelShape->SetSphere(1.0f); wheelBody->SetFriction(1.0f); wheelBody->SetMass(1.0f); wheelBody->SetLinearDamping(0.2f); // Some air resistance wheelBody->SetAngularDamping(0.75f); // Could also use rolling friction wheelBody->SetCollisionLayer(1); wheelConstraint->SetConstraintType(CONSTRAINT_HINGE); wheelConstraint->SetOtherBody(GetComponent<RigidBody>()); // Connect to the hull body wheelConstraint->SetWorldPosition(wheelNode->GetPosition()); // Set constraint's both ends at wheel's location wheelConstraint->SetAxis(Vector3::UP); // Wheel rotates around its local Y-axis wheelConstraint->SetOtherAxis(offset.x_ >= 0.0 ? Vector3::RIGHT : Vector3::LEFT); // Wheel's hull axis points either left or right wheelConstraint->SetLowLimit(Vector2(-180.0f, 0.0f)); // Let the wheel rotate freely around the axis wheelConstraint->SetHighLimit(Vector2(180.0f, 0.0f)); wheelConstraint->SetDisableCollision(true); // Let the wheel intersect the vehicle hull }
void on_tick(const interface::TickEvent &event) { log_d(MODULE, "entitytest::on_tick"); static uint a = 0; if(((a++) % 100) == 0){ main_context::access(m_server, [&](main_context::Interface *imc){ Scene *scene = imc->check_scene(m_main_scene); Node *n = scene->GetChild("Box"); n->SetPosition(Vector3(0.0f, 6.0f, 0.0f)); n->SetRotation(Quaternion(30, 60, 90)); Node *n2 = scene->GetChild("Box2"); n2->SetPosition(Vector3(-0.4f, 8.0f, 0.0f)); n2->SetRotation(Quaternion(30, 60, 90)); m_slow_count++; if(m_slow_count == 2){ Node *n = scene->CreateChild("Box"); n->SetPosition(Vector3(0.0f, 10.0f, 0.0f)); n->SetScale(Vector3(1.0f, 1.0f, 1.0f)); RigidBody *body = n->CreateComponent<RigidBody>(); CollisionShape *shape = n->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); body->SetMass(1.0); body->SetFriction(0.75f); // Model and material is set on client } }); return; } main_context::access(m_server, [&](main_context::Interface *imc){ Scene *scene = imc->check_scene(m_main_scene); Node *n = scene->GetChild("Box"); //n->Translate(Vector3(0.1f, 0, 0)); Vector3 p = n->GetPosition(); log_v(MODULE, "Position: %s", p.ToString().CString()); }); }
void VehicleDemo::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create scene subsystem components scene_->CreateComponent<Octree>(); scene_->CreateComponent<PhysicsWorld>(); // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene, // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load cameraNode_ = new Node(context_); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(500.0f); GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene_, camera)); // Create static scene content. First create a zone for ambient lighting and fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.5f, 0.5f, 0.7f)); zone->SetFogStart(300.0f); zone->SetFogEnd(500.0f); zone->SetBoundingBox(BoundingBox(-2000.0f, 2000.0f)); // Create a directional light with cascaded shadow mapping Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.3f, -0.5f, 0.425f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); light->SetSpecularIntensity(0.5f); // Create heightmap terrain with collision Node* terrainNode = scene_->CreateChild("Terrain"); terrainNode->SetPosition(Vector3::ZERO); Terrain* terrain = terrainNode->CreateComponent<Terrain>(); terrain->SetPatchSize(64); terrain->SetSpacing(Vector3(2.0f, 0.1f, 2.0f)); // Spacing between vertices and vertical resolution of the height map terrain->SetSmoothing(true); terrain->SetHeightMap(cache->GetResource<Image>("Textures/HeightMap.png")); terrain->SetMaterial(cache->GetResource<Material>("Materials/Terrain.xml")); // The terrain consists of large triangles, which fits well for occlusion rendering, as a hill can occlude all // terrain patches and other objects behind it terrain->SetOccluder(true); RigidBody* body = terrainNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(2); // Use layer bitmask 2 for static geometry CollisionShape* shape = terrainNode->CreateComponent<CollisionShape>(); shape->SetTerrain(); // Create 1000 mushrooms in the terrain. Always face outward along the terrain normal const unsigned NUM_MUSHROOMS = 1000; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) { Node* objectNode = scene_->CreateChild("Mushroom"); Vector3 position(Random(2000.0f) - 1000.0f, 0.0f, Random(2000.0f) - 1000.0f); position.y_ = terrain->GetHeight(position) - 0.1f; objectNode->SetPosition(position); // Create a rotation quaternion from up vector to terrain normal objectNode->SetRotation(Quaternion(Vector3::UP, terrain->GetNormal(position))); objectNode->SetScale(3.0f); StaticModel* object = objectNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl")); object->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml")); object->SetCastShadows(true); RigidBody* body = objectNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(2); CollisionShape* shape = objectNode->CreateComponent<CollisionShape>(); shape->SetTriangleMesh(object->GetModel(), 0); } }
void Ragdolls::CreateScene() { ResourceCache* cache = GetContext()->m_ResourceCache.get(); scene_ = new Scene(GetContext()); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must // exist before creating drawable components, the PhysicsWorld must exist before creating physics components. // Finally, create a DebugRenderer component so that we can draw physics debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<PhysicsWorld>(); scene_->CreateComponent<DebugRenderer>(); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.5f, 0.5f, 0.7f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light to the world. Enable cascaded shadows on it Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); { // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y Node* floorNode = scene_->CreateChild("Floor"); floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f)); floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // Make the floor physical by adding RigidBody and CollisionShape components RigidBody* body = floorNode->CreateComponent<RigidBody>(); // We will be spawning spherical objects in this sample. The ground also needs non-zero rolling friction so that // the spheres will eventually come to rest body->SetRollingFriction(0.15f); CollisionShape* shape = floorNode->CreateComponent<CollisionShape>(); // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.) shape->SetBox(Vector3::ONE); } // Create animated models for (int z = -1; z <= 1; ++z) { for (int x = -4; x <= 4; ++x) { Node* modelNode = scene_->CreateChild("Jack"); modelNode->SetPosition(Vector3(x * 5.0f, 0.0f, z * 5.0f)); modelNode->SetRotation(Quaternion(0.0f, 180.0f, 0.0f)); AnimatedModel* modelObject = modelNode->CreateComponent<AnimatedModel>(); modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl")); modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml")); modelObject->SetCastShadows(true); // Set the model to also update when invisible to avoid staying invisible when the model should come into // view, but does not as the bounding box is not updated modelObject->SetUpdateInvisible(true); // Create a rigid body and a collision shape. These will act as a trigger for transforming the // model into a ragdoll when hit by a moving object RigidBody* body = modelNode->CreateComponent<RigidBody>(); // The Trigger mode makes the rigid body only detect collisions, but impart no forces on the // colliding objects body->SetTrigger(true); CollisionShape* shape = modelNode->CreateComponent<CollisionShape>(); // Create the capsule shape with an offset so that it is correctly aligned with the model, which // has its origin at the feet shape->SetCapsule(0.7f, 2.0f, Vector3(0.0f, 1.0f, 0.0f)); // Create a custom component that reacts to collisions and creates the ragdoll modelNode->CreateComponent<CreateRagdoll>(); } } // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside // the scene, because we want it to be unaffected by scene load / save cameraNode_ = new Node(GetContext()); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->setFarClipDistance(300.0f); // Set an initial position for the camera scene node above the floor cameraNode_->SetPosition(Vector3(0.0f, 3.0f, -20.0f)); }
void NavigationMesh::GetTileGeometry(NavBuildData* build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box) { Matrix3x4 inverse = node_->GetWorldTransform().Inverse(); for (unsigned i = 0; i < geometryList.Size(); ++i) { if (box.IsInsideFast(geometryList[i].boundingBox_) != OUTSIDE) { const Matrix3x4& transform = geometryList[i].transform_; if (geometryList[i].component_->GetType() == OffMeshConnection::GetTypeStatic()) { OffMeshConnection* connection = static_cast<OffMeshConnection*>(geometryList[i].component_); Vector3 start = inverse * connection->GetNode()->GetWorldPosition(); Vector3 end = inverse * connection->GetEndPoint()->GetWorldPosition(); build->offMeshVertices_.Push(start); build->offMeshVertices_.Push(end); build->offMeshRadii_.Push(connection->GetRadius()); build->offMeshFlags_.Push((unsigned short)connection->GetMask()); build->offMeshAreas_.Push((unsigned char)connection->GetAreaID()); build->offMeshDir_.Push((unsigned char)(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0)); continue; } else if (geometryList[i].component_->GetType() == NavArea::GetTypeStatic()) { NavArea* area = static_cast<NavArea*>(geometryList[i].component_); NavAreaStub stub; stub.areaID_ = (unsigned char)area->GetAreaID(); stub.bounds_ = area->GetWorldBoundingBox(); build->navAreas_.Push(stub); continue; } #ifdef ATOMIC_PHYSICS CollisionShape* shape = dynamic_cast<CollisionShape*>(geometryList[i].component_); if (shape) { switch (shape->GetShapeType()) { case SHAPE_TRIANGLEMESH: { Model* model = shape->GetModel(); if (!model) continue; unsigned lodLevel = shape->GetLodLevel(); for (unsigned j = 0; j < model->GetNumGeometries(); ++j) AddTriMeshGeometry(build, model->GetGeometry(j, lodLevel), transform); } break; case SHAPE_CONVEXHULL: { ConvexData* data = static_cast<ConvexData*>(shape->GetGeometryData()); if (!data) continue; unsigned numVertices = data->vertexCount_; unsigned numIndices = data->indexCount_; unsigned destVertexStart = build->vertices_.Size(); for (unsigned j = 0; j < numVertices; ++j) build->vertices_.Push(transform * data->vertexData_[j]); for (unsigned j = 0; j < numIndices; ++j) build->indices_.Push(data->indexData_[j] + destVertexStart); } break; case SHAPE_BOX: { unsigned destVertexStart = build->vertices_.Size(); build->vertices_.Push(transform * Vector3(-0.5f, 0.5f, -0.5f)); build->vertices_.Push(transform * Vector3(0.5f, 0.5f, -0.5f)); build->vertices_.Push(transform * Vector3(0.5f, -0.5f, -0.5f)); build->vertices_.Push(transform * Vector3(-0.5f, -0.5f, -0.5f)); build->vertices_.Push(transform * Vector3(-0.5f, 0.5f, 0.5f)); build->vertices_.Push(transform * Vector3(0.5f, 0.5f, 0.5f)); build->vertices_.Push(transform * Vector3(0.5f, -0.5f, 0.5f)); build->vertices_.Push(transform * Vector3(-0.5f, -0.5f, 0.5f)); const unsigned indices[] = { 0, 1, 2, 0, 2, 3, 1, 5, 6, 1, 6, 2, 4, 5, 1, 4, 1, 0, 5, 4, 7, 5, 7, 6, 4, 0, 3, 4, 3, 7, 1, 0, 4, 1, 4, 5 }; for (unsigned j = 0; j < 36; ++j) build->indices_.Push(indices[j] + destVertexStart); } break; default: break; } continue; } #endif Drawable* drawable = dynamic_cast<Drawable*>(geometryList[i].component_); if (drawable) { const Vector<SourceBatch>& batches = drawable->GetBatches(); for (unsigned j = 0; j < batches.Size(); ++j) AddTriMeshGeometry(build, drawable->GetLodGeometry(j, geometryList[i].lodLevel_), transform); } } } }
void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive) { // Make sure nodes are not included twice if (processedNodes.Contains(node)) return; // Exclude obstacles and crowd agents from consideration if (node->HasComponent<Obstacle>() || node->HasComponent<CrowdAgent>()) return; processedNodes.Insert(node); Matrix3x4 inverse = node_->GetWorldTransform().Inverse(); #ifdef ATOMIC_PHYSICS // Prefer compatible physics collision shapes (triangle mesh, convex hull, box) if found. // Then fallback to visible geometry PODVector<CollisionShape*> collisionShapes; node->GetComponents<CollisionShape>(collisionShapes); bool collisionShapeFound = false; for (unsigned i = 0; i < collisionShapes.Size(); ++i) { CollisionShape* shape = collisionShapes[i]; if (!shape->IsEnabledEffective()) continue; ShapeType type = shape->GetShapeType(); if ((type == SHAPE_BOX || type == SHAPE_TRIANGLEMESH || type == SHAPE_CONVEXHULL) && shape->GetCollisionShape()) { Matrix3x4 shapeTransform(shape->GetPosition(), shape->GetRotation(), shape->GetSize()); NavigationGeometryInfo info; info.component_ = shape; info.transform_ = inverse * node->GetWorldTransform() * shapeTransform; info.boundingBox_ = shape->GetWorldBoundingBox().Transformed(inverse); geometryList.Push(info); collisionShapeFound = true; } } if (!collisionShapeFound) #endif { PODVector<Drawable*> drawables; node->GetDerivedComponents<Drawable>(drawables); for (unsigned i = 0; i < drawables.Size(); ++i) { /// \todo Evaluate whether should handle other types. Now StaticModel & TerrainPatch are supported, others skipped Drawable* drawable = drawables[i]; if (!drawable->IsEnabledEffective()) continue; NavigationGeometryInfo info; if (drawable->GetType() == StaticModel::GetTypeStatic()) info.lodLevel_ = static_cast<StaticModel*>(drawable)->GetOcclusionLodLevel(); else if (drawable->GetType() == TerrainPatch::GetTypeStatic()) info.lodLevel_ = 0; else continue; info.component_ = drawable; info.transform_ = inverse * node->GetWorldTransform(); info.boundingBox_ = drawable->GetWorldBoundingBox().Transformed(inverse); geometryList.Push(info); } } if (recursive) { const Vector<SharedPtr<Node> >& children = node->GetChildren(); for (unsigned i = 0; i < children.Size(); ++i) CollectGeometries(geometryList, children[i], processedNodes, recursive); } }
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl) { RigidBody* body = ctrl->GetRigidBody(); //this m_userPointer is just used for triggers, see CallbackTriggers body->m_userPointer = ctrl; body->setGravity( m_gravity ); m_controllers.push_back(ctrl); m_collisionWorld->AddCollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask()); assert(body->m_broadphaseHandle); BroadphaseInterface* scene = GetBroadphase(); CollisionShape* shapeinterface = ctrl->GetCollisionShape(); assert(shapeinterface); const SimdTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform(); body->m_cachedInvertedWorldTransform = body->m_worldTransform.inverse(); SimdPoint3 minAabb,maxAabb; shapeinterface->GetAabb(t,minAabb,maxAabb); float timeStep = 0.02f; //extent it with the motion SimdVector3 linMotion = body->getLinearVelocity()*timeStep; float maxAabbx = maxAabb.getX(); float maxAabby = maxAabb.getY(); float maxAabbz = maxAabb.getZ(); float minAabbx = minAabb.getX(); float minAabby = minAabb.getY(); float minAabbz = minAabb.getZ(); if (linMotion.x() > 0.f) maxAabbx += linMotion.x(); else minAabbx += linMotion.x(); if (linMotion.y() > 0.f) maxAabby += linMotion.y(); else minAabby += linMotion.y(); if (linMotion.z() > 0.f) maxAabbz += linMotion.z(); else minAabbz += linMotion.z(); minAabb = SimdVector3(minAabbx,minAabby,minAabbz); maxAabb = SimdVector3(maxAabbx,maxAabby,maxAabbz); }
void MeshInstanceEditor::_menu_option(int p_option) { Ref<Mesh> mesh = node->get_mesh(); if (mesh.is_null()) { err_dialog->set_text(TTR("Mesh is empty!")); err_dialog->popup_centered_minsize(); return; } switch (p_option) { case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: { bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); List<Node *> selection = editor_selection->get_selected_node_list(); if (selection.empty()) { Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape(); if (shape.is_null()) return; CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); StaticBody *body = memnew(StaticBody); body->add_child(cshape); Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); if (trimesh_shape) ur->create_action(TTR("Create Static Trimesh Body")); else ur->create_action(TTR("Create Static Convex Body")); ur->add_do_method(node, "add_child", body); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); ur->add_do_reference(body); ur->add_undo_method(node, "remove_child", body); ur->commit_action(); return; } if (trimesh_shape) ur->create_action(TTR("Create Static Trimesh Body")); else ur->create_action(TTR("Create Static Convex Body")); for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { MeshInstance *instance = E->get()->cast_to<MeshInstance>(); if (!instance) continue; Ref<Mesh> m = instance->get_mesh(); if (m.is_null()) continue; Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape(); if (shape.is_null()) continue; CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); StaticBody *body = memnew(StaticBody); body->add_child(cshape); Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner(); ur->add_do_method(instance, "add_child", body); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); ur->add_do_reference(body); ur->add_undo_method(instance, "remove_child", body); } ur->commit_action(); } break; case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE: case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: { if (node == get_tree()->get_edited_scene_root()) { err_dialog->set_text(TTR("This doesn't work on scene root!")); err_dialog->popup_centered_minsize(); return; } bool trimesh_shape = (p_option == MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape(); if (shape.is_null()) return; CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); Node *owner = node->get_owner(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); if (trimesh_shape) ur->create_action(TTR("Create Trimesh Shape")); else ur->create_action(TTR("Create Convex Shape")); ur->add_do_method(node->get_parent(), "add_child", cshape); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); ur->commit_action(); } break; case MENU_OPTION_CREATE_NAVMESH: { Ref<NavigationMesh> nmesh = memnew(NavigationMesh); if (nmesh.is_null()) return; nmesh->create_from_mesh(mesh); NavigationMeshInstance *nmi = memnew(NavigationMeshInstance); nmi->set_navigation_mesh(nmesh); Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Create Navigation Mesh")); ur->add_do_method(node, "add_child", nmi); ur->add_do_method(nmi, "set_owner", owner); ur->add_do_reference(nmi); ur->add_undo_method(node, "remove_child", nmi); ur->commit_action(); } break; case MENU_OPTION_CREATE_OUTLINE_MESH: { outline_dialog->popup_centered(Vector2(200, 90)); } break; } }
//============================================================================= //============================================================================= void Vehicle::Init() { // This function is called only from the main program when initially creating the vehicle, not on scene load ResourceCache* cache = GetSubsystem<ResourceCache>(); StaticModel* hullObject = node_->CreateComponent<StaticModel>(); hullBody_ = node_->CreateComponent<RigidBody>(); CollisionShape* hullColShape = node_->CreateComponent<CollisionShape>(); hullBody_->SetMass(1200.0f); hullBody_->SetLinearDamping(0.2f); // Some air resistance hullBody_->SetAngularDamping(0.5f); hullBody_->SetCollisionLayer(1); int rightIndex = 0; int upIndex = 1; int forwardIndex = 2; PhysicsWorld *pPhysWorld = GetScene()->GetComponent<PhysicsWorld>(); btDynamicsWorld *pbtDynWorld = (btDynamicsWorld*)pPhysWorld->GetWorld(); m_vehicleRayCaster = new btDefaultVehicleRaycaster( pbtDynWorld ); m_vehicle = new btRaycastVehicle( m_tuning, hullBody_->GetBody(), m_vehicleRayCaster ); pbtDynWorld->addVehicle( m_vehicle ); m_vehicle->setCoordinateSystem( rightIndex, upIndex, forwardIndex ); //Vector3 v3BoxExtents = Vector3::ONE;//Vector3(1.5f, 1.0f, 3.0f); hullObject->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/Chassis_001.mdl")); node_->SetScale( Vector3(1.0f, 1.0f, 1.0f) ); hullColShape->SetConvexHull(cache->GetResource<Model>("MyProjects/MiniCooper/test/collision.mdl")); //hullColShape->SetConvexHull(cache->GetResource<Model>("Models/Box.mdl")); //hullColShape->SetBox((hullObject->GetBoundingBox()).Size()); //hullColShape->SetTriangleMesh(cache->GetResource<Model>("Models/Box.mdl")); //hullColShape->SetSize(Vector3(1.0f, 1.0f, 3.0f)); //hullColShape->SetPosition((hullObject->GetBoundingBox()).Center() - Vector3(0.0f, 0.0f, 0.0f) ); //hullColShape->SetPosition( Vector3(0.0f, +0.2f, 0.0f) ); hullObject->SetCastShadows(true); Node* patricleTest = node_->CreateChild("patricleTest"); patricleTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/particleTest.xml")->GetRoot()); patricleTest->SetPosition(Vector3(0.0f, 0.2f, -2.0f)); Node* lightTest = node_->CreateChild("lightTest"); lightTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/lightTest.xml")->GetRoot()); lightTest->SetPosition(Vector3(0.0f, 0.2f, 2.0f)); //float connectionHeight = -0.4f;//1.2f; //float connectionHeight = 0.0f; bool isFrontWheel=true; btVector3 wheelDirectionCS0(0,-1,0); btVector3 wheelAxleCS(1,0,0); double wheelOffset = 0.5; // front right ////////////// Node* node_wheel_temp0 = GetScene()->CreateChild("node_wheel_temp0"); StaticModel* model_wheel_temp0 = node_wheel_temp0->CreateComponent<StaticModel>(); model_wheel_temp0->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_000.mdl")); model_wheel_temp0->ApplyMaterialList("MyProjects/MiniCooper/test/wheel_000.txt"); model_wheel_temp0->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); btVector3 connectionPointCS0((model_wheel_temp0->GetBoundingBox()).Center().x_,((model_wheel_temp0->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp0->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_0 = GetScene()->CreateChild("node_wheel_0"); node_wheel_0->SetPosition((model_wheel_temp0->GetBoundingBox()).Center()); node_wheel_0->SetRotation(Quaternion(0.0f, 0.0f, 90.0f)); node_wheel_temp0->SetParent(node_wheel_0); m_vpNodeWheel.Push( node_wheel_0 ); //SDL_Log( "node_wheel_temp0: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //SDL_Log( "node_wheel_temp0.HalfSize: %s \n", model_wheel_temp0->GetBoundingBox().HalfSize().ToString().CString() ); //SDL_Log("##################### \n"); //SDL_Log("node_wheel_temp0WorldP: %f, %f, %f \n", node_wheel_temp0->GetWorldPosition().x_, node_wheel_temp0->GetWorldPosition().y_, node_wheel_temp0->GetWorldPosition().z_); //SDL_Log("node_wheel_temp0P: %f, %f, %f \n", node_wheel_temp0->GetPosition().x_, node_wheel_temp0->GetPosition().y_, node_wheel_temp0->GetPosition().z_); //SDL_Log( "model_wheel_temp0BoundP: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //node_wheel_temp0->SetPosition(node_wheel_temp0->GetPosition() - (model_wheel_temp0->GetBoundingBox()).Center()); //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_); //v3Origin = v3Origin - Vector3(0.704, 0.379, 1.19); //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_); // front left ///////////// Node* node_wheel_temp1 = GetScene()->CreateChild("node_wheel_temp1"); StaticModel* model_wheel_temp1 = node_wheel_temp1->CreateComponent<StaticModel>(); model_wheel_temp1->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_001.mdl")); model_wheel_temp1->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp1->GetBoundingBox()).Center().x_,((model_wheel_temp1->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp1->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_1 = GetScene()->CreateChild("node_wheel_1"); node_wheel_1->SetPosition((model_wheel_temp1->GetBoundingBox()).Center()); node_wheel_1->SetRotation(Quaternion(0.0f, 0.0f, -90.0f)); node_wheel_temp1->SetParent(node_wheel_1); m_vpNodeWheel.Push( node_wheel_1 ); isFrontWheel = false; // back right ///////////// Node* node_wheel_temp2 = GetScene()->CreateChild("node_wheel_temp2"); StaticModel* model_wheel_temp2 = node_wheel_temp2->CreateComponent<StaticModel>(); model_wheel_temp2->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_002.mdl")); model_wheel_temp2->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp2->GetBoundingBox()).Center().x_,((model_wheel_temp2->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp2->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_2 = GetScene()->CreateChild("node_wheel_2"); node_wheel_2->SetPosition((model_wheel_temp2->GetBoundingBox()).Center()); node_wheel_2->SetRotation(Quaternion(0.0f, 0.0f, 90.0f)); node_wheel_temp2->SetParent(node_wheel_2); m_vpNodeWheel.Push( node_wheel_2 ); // back left ///////////// /// \brief objectNode3 Node* node_wheel_temp3 = GetScene()->CreateChild("node_wheel_temp3"); StaticModel* model_wheel_temp3 = node_wheel_temp3->CreateComponent<StaticModel>(); model_wheel_temp3->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_003.mdl")); model_wheel_temp3->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp3->GetBoundingBox()).Center().x_,((model_wheel_temp3->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp3->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_3 = GetScene()->CreateChild("node_wheel_2"); node_wheel_3->SetPosition((model_wheel_temp3->GetBoundingBox()).Center()); node_wheel_3->SetRotation(Quaternion(0.0f, 0.0f, -90.0f)); node_wheel_temp3->SetParent(node_wheel_3); m_vpNodeWheel.Push( node_wheel_3 ); /* for ( int i = 0; i < m_vehicle->getNumWheels(); i++ ) { btWheelInfo& wheel = m_vehicle->getWheelInfo( i ); wheel.m_suspensionStiffness = suspensionStiffness; wheel.m_wheelsDampingRelaxation = suspensionDamping; wheel.m_wheelsDampingCompression = suspensionCompression; wheel.m_frictionSlip = wheelFriction; wheel.m_rollInfluence = rollInfluence; } */ if ( m_vehicle ) { m_vehicle->resetSuspension(); for ( int i = 0; i < m_vehicle->getNumWheels(); i++ ) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); btTransform transform = m_vehicle->getWheelTransformWS( i ); /* //Vector3 v3Origin = ToVector3( transform.getOrigin() ); //Quaternion qRot = ToQuaternion( transform.getRotation() ); // create wheel node Node *wheelNode = GetScene()->CreateChild(); //wheelNode->SetPosition( v3Origin ); //btWheelInfo whInfo = m_vehicle->getWheelInfo( i ); //Vector3 v3PosLS = ToVector3( whInfo.m_chassisConnectionPointCS ); //wheelNode->SetRotation( v3PosLS.x_ >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f, 0.0f, 90.0f) ); //wheelNode->SetScale(Vector3(1.0f, 0.65f, 1.0f)); StaticModel *pWheel = wheelNode->CreateComponent<StaticModel>(); if(i == 0) pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl")); else pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl")); if(i == 0) { //wheelNode->SetPosition( Vector3(50,50,50) ); //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f)); }else { //wheelNode->SetPosition( v3Origin ); //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f)); } m_vpNodeWheel.Push( wheelNode ); //pWheel->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_004.mdl")); pWheel->SetMaterial(cache->GetResource<Material>("MyProjects/SimpeCar/TireTextureMaterial.xml")); pWheel->SetCastShadows(true); */ } } }
void PhysicsStressTest::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must // exist before creating drawable components, the PhysicsWorld must exist before creating physics components. // Finally, create a DebugRenderer component so that we can draw physics debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<PhysicsWorld>(); scene_->CreateComponent<DebugRenderer>(); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.5f, 0.5f, 0.7f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light to the world. Enable cascaded shadows on it Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); { // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y Node* floorNode = scene_->CreateChild("Floor"); floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f)); floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // Make the floor physical by adding RigidBody and CollisionShape components RigidBody* body = floorNode->CreateComponent<RigidBody>(); CollisionShape* shape = floorNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); } { // Create static mushrooms with triangle mesh collision const unsigned NUM_MUSHROOMS = 50; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) { Node* mushroomNode = scene_->CreateChild("Mushroom"); mushroomNode->SetPosition(Vector3(Random(400.0f) - 200.0f, 0.0f, Random(400.0f) - 200.0f)); mushroomNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f)); mushroomNode->SetScale(5.0f + Random(5.0f)); StaticModel* mushroomObject = mushroomNode->CreateComponent<StaticModel>(); mushroomObject->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl")); mushroomObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml")); mushroomObject->SetCastShadows(true); RigidBody* body = mushroomNode->CreateComponent<RigidBody>(); CollisionShape* shape = mushroomNode->CreateComponent<CollisionShape>(); // By default the highest LOD level will be used, the LOD level can be passed as an optional parameter shape->SetTriangleMesh(mushroomObject->GetModel()); } } { // Create a large amount of falling physics objects const unsigned NUM_OBJECTS = 1000; for (unsigned i = 0; i < NUM_OBJECTS; ++i) { Node* boxNode = scene_->CreateChild("Box"); boxNode->SetPosition(Vector3(0.0f, i * 2.0f + 100.0f, 0.0f)); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml")); boxObject->SetCastShadows(true); // Give the RigidBody mass to make it movable and also adjust friction RigidBody* body = boxNode->CreateComponent<RigidBody>(); body->SetMass(1.0f); body->SetFriction(1.0f); // Disable collision event signaling to reduce CPU load of the physics simulation body->SetCollisionEventMode(COLLISION_NEVER); CollisionShape* shape = boxNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); } } // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside // the scene, because we want it to be unaffected by scene load / save cameraNode_ = new Node(context_); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the floor cameraNode_->SetPosition(Vector3(0.0f, 3.0f, -20.0f)); }
void SimulationIsland::UpdateAabbs(IDebugDraw* debugDrawer,BroadphaseInterface* scene,float timeStep) { std::vector<CcdPhysicsController*>::iterator i; // // update aabbs, only for moving objects (!) // for (i=m_controllers.begin(); !(i==m_controllers.end()); i++) { CcdPhysicsController* ctrl = (*i); RigidBody* body = ctrl->GetRigidBody(); SimdPoint3 minAabb,maxAabb; CollisionShape* shapeinterface = ctrl->GetCollisionShape(); shapeinterface->CalculateTemporalAabb(body->getCenterOfMassTransform(), body->getLinearVelocity(), //body->getAngularVelocity(), SimdVector3(0.f,0.f,0.f),//no angular effect for now //body->getAngularVelocity(), timeStep,minAabb,maxAabb); SimdVector3 manifoldExtraExtents(gContactBreakingTreshold,gContactBreakingTreshold,gContactBreakingTreshold); minAabb -= manifoldExtraExtents; maxAabb += manifoldExtraExtents; BroadphaseProxy* bp = body->m_broadphaseHandle; if (bp) { SimdVector3 color (1,1,0); class IDebugDraw* m_debugDrawer = 0; /* if (m_debugDrawer) { //draw aabb switch (body->GetActivationState()) { case ISLAND_SLEEPING: { color.setValue(1,1,1); break; } case WANTS_DEACTIVATION: { color.setValue(0,0,1); break; } case ACTIVE_TAG: { break; } case DISABLE_DEACTIVATION: { color.setValue(1,0,1); }; }; if (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_DrawAabb) { DrawAabb(m_debugDrawer,minAabb,maxAabb,color); } } */ if ( (maxAabb-minAabb).length2() < 1e12f) { scene->SetAabb(bp,minAabb,maxAabb); } else { //something went wrong, investigate //removeCcdPhysicsController(ctrl); body->SetActivationState(DISABLE_SIMULATION); static bool reportMe = true; if (reportMe) { reportMe = false; printf("Overflow in AABB, object removed from simulation \n"); printf("If you can reproduce this, please email [email protected]\n"); printf("Please include above information, your Platform, version of OS.\n"); printf("Thanks.\n"); } } } } }
void CharacterDemo::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create scene subsystem components scene_->CreateComponent<Octree>(); scene_->CreateComponent<PhysicsWorld>(); // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene, // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load cameraNode_ = new Node(context_); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene_, camera)); // Create static scene content. First create a zone for ambient lighting and fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.5f, 0.5f, 0.7f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); // Create a directional light with cascaded shadow mapping Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.3f, -0.5f, 0.425f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); light->SetSpecularIntensity(0.5f); // Create the floor object Node* floorNode = scene_->CreateChild("Floor"); floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f)); floorNode->SetScale(Vector3(200.0f, 1.0f, 200.0f)); StaticModel* object = floorNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("Models/Box.mdl")); object->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); RigidBody* body = floorNode->CreateComponent<RigidBody>(); // Use collision layer bit 2 to mark world scenery. This is what we will raycast against to prevent camera from going // inside geometry body->SetCollisionLayer(2); CollisionShape* shape = floorNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); // Create mushrooms of varying sizes const unsigned NUM_MUSHROOMS = 60; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) { Node* objectNode = scene_->CreateChild("Mushroom"); objectNode->SetPosition(Vector3(Random(180.0f) - 90.0f, 0.0f, Random(180.0f) - 90.0f)); objectNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f)); objectNode->SetScale(2.0f + Random(5.0f)); StaticModel* object = objectNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl")); object->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml")); object->SetCastShadows(true); RigidBody* body = objectNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(2); CollisionShape* shape = objectNode->CreateComponent<CollisionShape>(); shape->SetTriangleMesh(object->GetModel(), 0); } // Create movable boxes. Let them fall from the sky at first const unsigned NUM_BOXES = 100; for (unsigned i = 0; i < NUM_BOXES; ++i) { float scale = Random(2.0f) + 0.5f; Node* objectNode = scene_->CreateChild("Box"); objectNode->SetPosition(Vector3(Random(180.0f) - 90.0f, Random(10.0f) + 10.0f, Random(180.0f) - 90.0f)); objectNode->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f))); objectNode->SetScale(scale); StaticModel* object = objectNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("Models/Box.mdl")); object->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); object->SetCastShadows(true); RigidBody* body = objectNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(2); // Bigger boxes will be heavier and harder to move body->SetMass(scale * 2.0f); CollisionShape* shape = objectNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); } }