void BulletPhysics::SyncVisibleScene() { // keep graphics and physics in sync // check all existing object bodies for changes // if there is a change, send appropriate event to game system for (auto it = m_ObjectIdToRigidBody.begin(); it != m_ObjectIdToRigidBody.end(); ++it) { const GameObjectId id = it->first; // get the motion state that is updated by bullet sdk const ObjectMotionState* objMotionState = static_cast<ObjectMotionState*>(it->second->getMotionState()); CB_ASSERT(objMotionState); StrongGameObjectPtr pGameObject = MakeStrongPtr(g_pApp->m_pGame->GetGameObject(id)); if (pGameObject && objMotionState) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(pGameObject->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { // if the objects world position and physics position are different, update if (pTransformComponent->GetTransform() != objMotionState->m_WorldToPositionTransform) { // sync the transform and dispatch an event that an object has moved pTransformComponent->SetTransform(objMotionState->m_WorldToPositionTransform); shared_ptr<Event_MoveGameObject> pEvent(CB_NEW Event_MoveGameObject(id, objMotionState->m_WorldToPositionTransform)); IEventManager::Get()->QueueEvent(pEvent); } } } } }
void TeapotWarsLogic::EndSteerDelegate(IEventDataPtr pEventData) { shared_ptr<EvtData_StartThrust> pCastEventData = static_pointer_cast<EvtData_StartThrust>(pEventData); StrongActorPtr pActor = MakeStrongPtr(VGetActor(pCastEventData->GetActorId())); if (pActor) { shared_ptr<PhysicsComponent> pPhysicalComponent = MakeStrongPtr(pActor->GetComponent<PhysicsComponent>(PhysicsComponent::g_Name)); if (pPhysicalComponent) { pPhysicalComponent->RemoveAngularAcceleration(); } } }
void MeshRenderComponent::RenderInstance(const ModelInstance* inst, const shared_ptr<CameraNode> _pCamera) { ModelAsset* asset = inst->asset; Program* shaders = asset->Shaders; weak_ptr<TransformComponent> pWeakTransform = m_pOwner->GetComponent<TransformComponent>(TransformComponent::GetIdFromName(TransformComponent::g_Name)); shared_ptr<TransformComponent> pTransform = MakeStrongPtr(pWeakTransform); //bind the shaders shaders->Use(); //set the shader uniforms shaders->setUniform("camera", _pCamera->Matrix()); // shaders->setUniform("model", inst->transform); if (pTransform) shaders->setUniform("model", pTransform->GetTransform()); else shaders->setUniform("model", inst->transform); shaders->setUniform("tex", 0); //set to 0 because the texture will be bound to GL_TEXTURE0 //bind the texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, asset->DiffuseTexture->object()); //bind VAO and draw glBindVertexArray(asset->VAO); glDrawArrays(asset->DrawType, asset->DrawStart, asset->DrawCount); //unbind everything glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); shaders->StopUsing(); }
void BulletPhysics::CreateTrigger(WeakGameObjectPtr pGameObject, const Vec3& position, const float dim) { StrongGameObjectPtr pStrongObject = MakeStrongPtr(pGameObject); if (!pStrongObject) { CB_ERROR("Must attach a game object to the trigger"); return; } // create the collision body btBoxShape* boxShape = new btBoxShape(Vec3_to_btVector3(Vec3(dim, dim, dim))); // 0 mass, this trigger is not moveable const btScalar mass = 0; // set the initial position of the trigger from the object Mat4x4 triggerTransform = Mat4x4::Identity; triggerTransform.SetPosition(position); ObjectMotionState* motionState = CB_NEW ObjectMotionState(triggerTransform); // create the rigid body btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, boxShape, btVector3(0, 0, 0)); btRigidBody* body = new btRigidBody(rbInfo); // add the body to the world m_DynamicsWorld->addRigidBody(body); // mark the body as a trigger so it does not physically collide with object body->setCollisionFlags(body->getCollisionFlags() | btRigidBody::CF_NO_CONTACT_RESPONSE); // update the maps m_ObjectIdToRigidBody[pStrongObject->GetId()] = body; m_RigidBodyToObjectId[body] = pStrongObject->GetId(); }
shared_ptr<SceneNode> SphereRenderComponent::CreateSceneNode() { // get the transform shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (!pTransformComponent) { // can't render without a transform return shared_ptr<SceneNode>(); } WeakBaseRenderComponentPtr weakThis(this); if (WindowsApp::GetRendererImpl() == WindowsApp::Renderer_D3D9) { // create the sphere Mesh ID3DXMesh* pSphereMesh; D3DXCreateSphere(DXUTGetD3D9Device(), m_Radius, m_Segments, m_Segments, &pSphereMesh, NULL); shared_ptr<SceneNode> sphere(CB_NEW D3DShaderMeshNode9(m_pOwner->GetId(), weakThis, pSphereMesh, "Effects\\Main.fx", RenderPass_Object, &pTransformComponent->GetTransform())); SAFE_RELEASE(pSphereMesh); return sphere; } else if (WindowsApp::GetRendererImpl() == WindowsApp::Renderer_D3D11) { shared_ptr<SceneNode> sphere(CB_NEW D3DShaderMeshNode11(m_pOwner->GetId(), weakThis, "art\\sphere.sdkmesh", RenderPass_Object, &pTransformComponent->GetTransform())); return sphere; } else { CB_ASSERT(0 && "Unknown Renderer Implementation in SphereRenderComponent::VCreateSceneNode"); return shared_ptr<SceneNode>(NULL); } }
void BulletPhysics::AddPointCloud(Vec3* verts, int numPoints, WeakGameObjectPtr pGameObject, const std::string& densityStr, const std::string& physicsMaterial) { // used to create a convex mesh shape StrongGameObjectPtr pStrongObject = MakeStrongPtr(pGameObject); if (!pStrongObject) { CB_ERROR("Must attach a game object to the point cloud"); return; } btConvexHullShape* shape = new btConvexHullShape(); // add points to the shape one at a time for (int i = 0; i < numPoints; i++) { shape->addPoint(Vec3_to_btVector3(verts[i])); } // approximate mass using bounding box btVector3 aabbMin(0, 0, 0), aabbMax(0, 0, 0); shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax); const btVector3 aabbExtents = aabbMax - aabbMin; float specificGravity = LookupSpecificGravity(densityStr); const float volume = aabbExtents.x() * aabbExtents.y() * aabbExtents.z(); const btScalar mass = volume * specificGravity; AddShape(pStrongObject, shape, mass, physicsMaterial); }
//==================================================== // TeapotRenderComponent definitions //==================================================== shared_ptr<SceneNode> TeapotRenderComponent::CreateSceneNode() { // get the transform shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); switch (WindowsApp::GetRendererImpl()) { case WindowsApp::Renderer_D3D9: return shared_ptr<SceneNode>(CB_NEW D3DTeapotMeshNode9(m_pOwner->GetId(), weakThis, "Effects\\Main.fx", RenderPass_Object, &pTransformComponent->GetTransform())); case WindowsApp::Renderer_D3D11: { Mat4x4 rot90; rot90.BuildRotationY(-CB_PI / 2.0f); shared_ptr<SceneNode> parent(CB_NEW SceneNode(m_pOwner->GetId(), weakThis, RenderPass_Object, &pTransformComponent->GetTransform())); shared_ptr<SceneNode> teapot(CB_NEW D3DTeapotMeshNode11(INVALID_GAMEOBJECT_ID, weakThis, RenderPass_Object, &rot90)); parent->AddChild(teapot); return parent; } default: CB_ERROR("Unknown Renderer Implementation in TeapotRenderComponent"); } } return shared_ptr<SceneNode>(); }
// // GetActorXmlSize - Chapter 22, page 757 // int GetActorXmlSize ( ActorId actorId ) { StrongActorPtr pActor = MakeStrongPtr(g_pApp->m_pGame->VGetActor(actorId)); if ( !pActor ) { return 0; } std::string xml = pActor->ToXML(); return xml.length(); }
// // GetActorXml - Chapter 22, page 758 // void GetActorXml ( int *actorXMLAddress, ActorId actorId ) { StrongActorPtr pActor = MakeStrongPtr(g_pApp->m_pGame->VGetActor(actorId)); if ( !pActor ) { return; } std::string xml = pActor->ToXML(); strncpy_s(reinterpret_cast<char *>(actorXMLAddress), xml.length()+1, xml.c_str(), xml.length()); }
LuaPlus::LuaObject BaseScriptComponent::GetLookAt(void) const { LuaPlus::LuaObject ret; shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) LuaStateManager::Get()->ConvertVec3ToTable(pTransformComponent->GetLookAt(), ret); else ret.AssignNil(LuaStateManager::Get()->GetLuaState()); return ret; }
void TeapotWarsLogic::VMoveActor(const ActorId id, Mat4x4 const &mat) { BaseGameLogic::VMoveActor(id, mat); // [rez] HACK: This will be removed whenever the gameplay update stuff is in. This is meant to model the death // zone under the grid. // FUTURE WORK - This would make a great basis for a Trigger actor that ran a LUA script when other // actors entered or left it! StrongActorPtr pActor = MakeStrongPtr(VGetActor(id)); if (pActor) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(pActor->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent && pTransformComponent->GetPosition().y < -25) { shared_ptr<EvtData_Destroy_Actor> pDestroyActorEvent(GCC_NEW EvtData_Destroy_Actor(id)); IEventManager::Get()->VQueueEvent(pDestroyActorEvent); } } }
LuaPlus::LuaObject LuaScriptComponent::GetPos() { // return the objects position to lua LuaPlus::LuaObject ret; shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) LuaStateManager::Get()->ConvertVec3ToTable(pTransformComponent->GetPosition(), ret); else ret.AssignNil(LuaStateManager::Get()->GetLuaState()); return ret; }
float BaseScriptComponent::GetYOrientationRadians(void) const { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { return (GetYRotationFromVector(pTransformComponent->GetLookAt())); } else { AC_ERROR("Attempting to call GetYOrientationRadians() on actor with no physical component"); return 0; } }
void PhysicsComponent::VUpdate(int deltaMs) { // get the transform component shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (!pTransformComponent) { GCC_ERROR("No transform component!"); return; } // get the direction the object is facing Mat4x4 transform = pTransformComponent->GetTransform(); if (m_acceleration != 0) { // calculate the acceleration this frame float accelerationToApplyThisFrame = m_acceleration / 1000.f * (float)deltaMs; // Get the current velocity vector and convert to a scalar. The velocity vector is a combination of // the direction this actor is going in and the speed of the actor. The scalar is just the speed // component. Vec3 velocity(m_pGamePhysics->VGetVelocity(m_pOwner->GetId())); float velocityScalar = velocity.Length(); Vec3 direction(transform.GetDirection()); m_pGamePhysics->VApplyForce(direction, accelerationToApplyThisFrame, m_pOwner->GetId()); // logging // [rez] Comment this back in if you want to debug the physics thrust & rotation stuff. It spams quite // a bit of info the output window so I'm commenting it out for now. /* GCC_LOG("Actor", "Acceleration: " + ToStr(accelerationToApplyThisFrame) + "; velocityScalar: " + ToStr(velocityScalar) + \ "; direction: " + ToStr(direction) + "; direction.Length(): " + ToStr(direction.Length()) + \ "; velocity: " + ToStr(velocity) + "; velocity.Length(): " + ToStr(velocity.Length())); */ } if (m_angularAcceleration != 0) { // calculate the acceleration this frame float angularAccelerationToApplyThisFrame = m_angularAcceleration / 1000.f * (float)deltaMs; m_pGamePhysics->VApplyTorque(transform.GetUp(), angularAccelerationToApplyThisFrame, m_pOwner->GetId()); // logging // [rez] Comment this back in if you want to debug the physics thrust & rotation stuff. It spams quite // a bit of info the output window so I'm commenting it out for now. //GCC_LOG("Actor", "Angular Acceleration: " + ToStr(angularAccelerationToApplyThisFrame) ); } }
void PhysicsComponent::SetPosition(float x, float y, float z) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { Mat4x4 transform = pTransformComponent->GetTransform(); Vec3 position = Vec3(x, y, z); transform.SetPosition(position); KinematicMove(transform); } else GCC_ERROR("Attempting to call RotateY() on actor with no trnasform component"); }
float LuaScriptComponent::GetYOrientationRadians() const { // return the look at vector of an object to lua shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { return (GetYRotationFromVector(pTransformComponent->GetLookAt())); } else { CB_ERROR("Attempting to call GetYOrientationRadians() on object with no physical component"); return 0.0f; } }
void BaseScriptComponent::SetPos(LuaPlus::LuaObject newPos) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { Vec3 pos; LuaStateManager::Get()->ConvertTableToVec3(newPos, pos); pTransformComponent->SetPosition(pos); } else { AC_ERROR("Attempting to call SetPos() on an actor with no physcial component; ActorId: " + ToStr(m_pOwner->GetId())); } }
void WatchMeProcess::VOnUpdate(unsigned long deltaMs) { StrongActorPtr pTarget = MakeStrongPtr(g_pApp->m_pGame->VGetActor(m_target)); StrongActorPtr pMe = MakeStrongPtr(g_pApp->m_pGame->VGetActor(m_me)); shared_ptr<TransformComponent> pTargetTransform = MakeStrongPtr(pTarget->GetComponent<TransformComponent>(TransformComponent::g_Name)); shared_ptr<TransformComponent> pMyTransform = MakeStrongPtr(pMe->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (!pTarget || !pMe || !pTargetTransform || !pMyTransform) { GCC_ERROR("This shouldn't happen"); Fail(); } Vec3 targetPos = pTargetTransform->GetPosition(); Mat4x4 myTransform = pMyTransform->GetTransform(); Vec3 myDir = myTransform.GetDirection(); myDir = Vec3(0.0f, 0.0f, 1.0f); Vec3 myPos = pMyTransform->GetPosition(); Vec3 toTarget = targetPos - myPos; toTarget.Normalize(); float dotProduct = myDir.Dot(toTarget); Vec3 crossProduct = myDir.Cross(toTarget); float angleInRadians = acos(dotProduct); if (crossProduct.y < 0) angleInRadians = -angleInRadians; Mat4x4 rotation; rotation.BuildRotationY(angleInRadians); rotation.SetPosition(myPos); pMyTransform->SetTransform(rotation); }
void BulletPhysics::AddShape(StrongGameObjectPtr pGameObject, btCollisionShape* shape, float mass, const std::string& physicsMaterial) { CB_ASSERT(pGameObject); // make sure this object is only added once GameObjectId id = pGameObject->GetId(); CB_ASSERT(m_ObjectIdToRigidBody.find(id) == m_ObjectIdToRigidBody.end() && "GameObjects can only have one physics body"); // look up material MaterialData material(LookupMaterialData(physicsMaterial)); // local inertia defines how the objects mass is distributed btVector3 localInertia(0.0f, 0.0f, 0.0f); if (mass > 0.0f) { shape->calculateLocalInertia(mass, localInertia); } // get the objects transform Mat4x4 transform = Mat4x4::Identity; shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(pGameObject->GetComponent<TransformComponent>(TransformComponent::g_Name)); CB_ASSERT(pTransformComponent); if (pTransformComponent) { transform = pTransformComponent->GetTransform(); } else { // Physics can't work on an object that doesn't have a TransformComponent return; } ObjectMotionState* motionState = CB_NEW ObjectMotionState(transform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, shape, localInertia); // set up material properties rbInfo.m_restitution = material.m_Restitution; rbInfo.m_friction = material.m_Friction; // add body to physics world btRigidBody* body = new btRigidBody(rbInfo); m_DynamicsWorld->addRigidBody(body); // update the maps m_ObjectIdToRigidBody[id] = body; m_RigidBodyToObjectId[body] = id; }
void PhysicsComponent::RotateY(float angleRadians) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { glm::mat4 transform = pTransformComponent->GetTransform(); glm::vec3 position = GetPosition(transform); glm::mat4 rotateY; rotateY = glm::rotate(rotateY, angleRadians, g_YAxis); ::SetPosition(rotateY, position); KinematicMove(rotateY); } else LOG_ERROR("Attempting to call RotateY() on actor with no transform component"); }
void NetworkGameView::NewGameObjectDelegate(IEventPtr pEvent) { // get a pointer to the game object shared_ptr<Event_NewGameObject> pCastEvent = static_pointer_cast<Event_NewGameObject>(pEvent); GameObjectId objectId = pCastEvent->GetObjectId(); StrongGameObjectPtr pObject = MakeStrongPtr(g_pApp->m_pGame->GetGameObject(objectId)); if (pObject && pObject->GetType() == "Teapot") { if (pCastEvent->GetViewId() == m_ViewId) { m_GameObjectId = objectId; shared_ptr<Event_NetworkPlayerObjectAssignment> pEvent(CB_NEW Event_NetworkPlayerObjectAssignment(m_GameObjectId, m_SockId)); IEventManager::Get()->QueueEvent(pEvent); } } }
void PhysicsComponent::RotateY(float angleRadians) { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { Mat4x4 transform = pTransformComponent->GetTransform(); Vec3 position = transform.GetPosition(); Mat4x4 rotateY; rotateY.BuildRotationY(angleRadians); rotateY.SetPosition(position); KinematicMove(rotateY); } else GCC_ERROR("Attempting to call RotateY() on actor with no transform component"); }
void BulletPhysics::AddBox(const Vec3& dimensions, WeakGameObjectPtr pGameObject, const std::string& densityStr, const std::string& physicsMaterial) { StrongGameObjectPtr pStrongObject = MakeStrongPtr(pGameObject); if (!pStrongObject) { CB_ERROR("Must attach a game object to the box"); return; } // create box collider btBoxShape* boxShape = new btBoxShape(Vec3_to_btVector3(dimensions)); // calculate mass using specific gravity (density) float specificGravity = LookupSpecificGravity(densityStr); const float volume = dimensions.x * dimensions.y * dimensions.z; const btScalar mass = volume * specificGravity; AddShape(pStrongObject, boxShape, mass, physicsMaterial); }
void BulletPhysics::AddSphere(float radius, WeakGameObjectPtr pGameObject, const std::string& densityStr, const std::string& physicsMaterial) { StrongGameObjectPtr pStrongObject = MakeStrongPtr(pGameObject); if (!pStrongObject) { CB_ERROR("Must attach a game object to the sphere"); return; } // create a sphere collider btSphereShape* sphereShape = new btSphereShape(radius); // calculate mass using specific gravity (density) float specificGravity = LookupSpecificGravity(densityStr); const float volume = (4.0f / 3.0f) * CB_PI * radius * radius * radius; const btScalar mass = volume * specificGravity; AddShape(pStrongObject, sphereShape, mass, physicsMaterial); }
shared_ptr<SceneNode> LightRenderComponent::CreateSceneNode() { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); switch (WindowsApp::GetRendererImpl()) { case WindowsApp::Renderer::Renderer_D3D11: return shared_ptr<SceneNode>(CB_NEW D3DLightNode11(m_pOwner->GetId(), weakThis, m_Properties, &(pTransformComponent->GetTransform()))); case WindowsApp::Renderer::Renderer_D3D9: return shared_ptr<SceneNode>(CB_NEW D3DLightNode9(m_pOwner->GetId(), weakThis, m_Properties, &(pTransformComponent->GetTransform()))); default: CB_ASSERT(0 && "Uknown render implementation in LightRenderComponent"); } } return shared_ptr<SceneNode>(); }
shared_ptr<SceneNode> GridRenderComponent::CreateSceneNode() { shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name)); if (pTransformComponent) { WeakBaseRenderComponentPtr weakThis(this); switch (WindowsApp::GetRendererImpl()) { case WindowsApp::Renderer_D3D9: return shared_ptr<SceneNode>(CB_NEW D3DGrid9(m_pOwner->GetId(), weakThis, &(pTransformComponent->GetTransform()))); case WindowsApp::Renderer_D3D11: return shared_ptr<SceneNode>(CB_NEW D3DGrid11(m_pOwner->GetId(), weakThis, &(pTransformComponent->GetTransform()))); default: CB_ERROR("Unknown Renderer Implementation in GridRenderComponent"); } } return shared_ptr<SceneNode>(); }
void LuaScriptComponent::RotateY(float angleRadians) { shared_ptr<PhysicsComponent> pPhysicalComponent = MakeStrongPtr(m_pOwner->GetComponent<PhysicsComponent>(PhysicsComponent::g_Name)); if (pPhysicalComponent) pPhysicalComponent->RotateY(angleRadians); }
void LuaScriptComponent::SetPosition(float x, float y, float z) { shared_ptr<PhysicsComponent> pPhysicalComponent = MakeStrongPtr(m_pOwner->GetComponent<PhysicsComponent>(PhysicsComponent::g_Name)); if (pPhysicalComponent) pPhysicalComponent->SetPosition(x, y, z); }
void LuaScriptComponent::Stop() { shared_ptr<PhysicsComponent> pPhysicalComponent = MakeStrongPtr(m_pOwner->GetComponent<PhysicsComponent>(PhysicsComponent::g_Name)); if (pPhysicalComponent) pPhysicalComponent->Stop(); }