void BulletPhysics::LoadXml() { // load physics config file TiXmlElement* pRoot = XmlResourceLoader::LoadAndReturnRootXmlElement("config\\Physics.xml"); CB_ASSERT(pRoot); // load materials TiXmlElement* pParentNode = pRoot->FirstChildElement("PhysicsMaterials"); CB_ASSERT(pParentNode); for (TiXmlElement* pNode = pParentNode->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement()) { double restitution = 0.0; double friction = 0.0; pNode->Attribute("restitution", &restitution); pNode->Attribute("friction", &friction); m_MaterialTable.insert(std::make_pair(pNode->Value(), MaterialData((float)restitution, (float)friction))); } // load densities pParentNode = pRoot->FirstChildElement("DensityTable"); CB_ASSERT(pParentNode); for (TiXmlElement* pNode = pParentNode->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement()) { m_DensityTable.insert(std::make_pair(pNode->Value(), (float)atof(pNode->FirstChild()->Value()))); } }
bool EventManager::AbortEvent(const EventType& type, bool allOfType) { CB_ASSERT(m_ActiveQueue >= 0); CB_ASSERT(m_ActiveQueue < EVENTMANAGER_NUM_QUEUES); bool success = false; // find the event type in the map EventListenerMap::iterator findIt = m_EventListeners.find(type); if (findIt != m_EventListeners.end()) { // get the active event queue EventQueue& queue = m_Queues[m_ActiveQueue]; auto it = queue.begin(); while (it != queue.end()) { auto thisIt = it; ++it; // remove the first occurrence of this event type from the queue, // if allOfType is true, remove all occurrences if ((*thisIt)->GetEventType() == type) { queue.erase(thisIt); success = true; if (!allOfType) break; } } } return success; }
bool EventManager::QueueEvent(const IEventPtr& pEvent) { CB_ASSERT(m_ActiveQueue >= 0); CB_ASSERT(m_ActiveQueue < EVENTMANAGER_NUM_QUEUES); if (!pEvent) { CB_ERROR("Invalid Event"); return false; } CB_LOG("Events", "Attempting to queue event: " + std::string(pEvent->GetName())); // make sure there are listeners for this event auto findIt = m_EventListeners.find(pEvent->GetEventType()); if (findIt != m_EventListeners.end()) { m_Queues[m_ActiveQueue].push_back(pEvent); CB_LOG("Events", "Successfully queued event: " + std::string(pEvent->GetName())); return true; } else { CB_LOG("Events", "No listeners for event: " + std::string(pEvent->GetName())); return false; } }
void BulletPhysics::BulletInternalTickCallback(btDynamicsWorld* world, btScalar timeStep) { // called after bullet sdk performs its internal step CB_ASSERT(world); CB_ASSERT(world->getWorldUserInfo()); BulletPhysics* bulletPhysics = static_cast<BulletPhysics*>(world->getWorldUserInfo()); CollisionPairs currentTickCollisionPairs; // look at all existing collisions btDispatcher* dispatcher = world->getDispatcher(); const int numManifolds = dispatcher->getNumManifolds(); for (int i = 0; i < numManifolds; i++) { // get the manifold which is the data corresponding to a contact point between two colliders const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); CB_ASSERT(manifold); // get the colliding bodies const btRigidBody* body0 = static_cast<const btRigidBody *>(manifold->getBody0()); const btRigidBody* body1 = static_cast<const btRigidBody *>(manifold->getBody1()); // swap them if need be const bool swapped = body0 > body1; const btRigidBody* sortedBody0 = swapped ? body1 : body0; const btRigidBody* sortedBody1 = swapped ? body0 : body1; // insert the collision pair into the set const CollisionPair pair = std::make_pair(sortedBody0, sortedBody1); currentTickCollisionPairs.insert(pair); // if this is a new contact, send an event if (bulletPhysics->m_PreviousTickCollisionPairs.find(pair) == bulletPhysics->m_PreviousTickCollisionPairs.end()) { bulletPhysics->SendCollisionPairAddEvent(manifold, body0, body1); } } CollisionPairs removedCollisionPairs; // use set difference to see which collisions existed last tick but are no longer colliding std::set_difference(bulletPhysics->m_PreviousTickCollisionPairs.begin(), bulletPhysics->m_PreviousTickCollisionPairs.end(), currentTickCollisionPairs.begin(), currentTickCollisionPairs.end(), std::inserter(removedCollisionPairs, removedCollisionPairs.begin())); // send collision exit events for (auto it = removedCollisionPairs.begin(); it != removedCollisionPairs.end(); ++it) { const btRigidBody* body0 = it->first; const btRigidBody* body1 = it->second; bulletPhysics->SendCollisionPairRemoveEvent(body0, body1); } // update the collision pairs bulletPhysics->m_PreviousTickCollisionPairs = currentTickCollisionPairs; }
// remove a lua event listener void LuaInternalScriptExports::RemoveEventListener(unsigned long listenerId) { CB_ASSERT(s_pScriptEventListenerMgr); CB_ASSERT(listenerId != 0); // convert the listener handle back to a pointer and destroy it LuaScriptEventListener* pListener = reinterpret_cast<LuaScriptEventListener*>(listenerId); s_pScriptEventListenerMgr->DestroyListener(pListener); }
/******************************************************************************* ** 函数: cb_write ** 功能: 将datptr所指向的地址中的datlen长度的数据写入到pmngr->bufptr中 ** 返回: 返回实际写入的数据长度, 字节为单位 ** 作者: avrbase_lei *******/ static cb_u32 cb_write(CircleBufferMngr *pmngr, cb_u8 *datptr, cb_u32 datlen) { cb_u32 writelen = 0, tmplen = 0; CB_ASSERT(NULL != pmngr); CB_ASSERT(NULL != pmngr->bufptr); if(cb_full(pmngr)) return 0; CB_GLOBAL_LOCK; tmplen = pmngr->buflen - pmngr->datalen; writelen = tmplen > datlen ? datlen : tmplen; if(pmngr->writepos < pmngr->readpos) { CB_MEMCPY( (void*)&pmngr->bufptr[pmngr->writepos], (void*)datptr, writelen); } else { tmplen = pmngr->buflen - pmngr->writepos; if(writelen <= tmplen) { CB_MEMCPY( (void*)&pmngr->bufptr[pmngr->writepos], (void*)datptr, writelen); } else { CB_MEMCPY( (void*)&pmngr->bufptr[pmngr->writepos], (void*)datptr, tmplen); CB_MEMCPY( (void*)pmngr->bufptr, (void*)&datptr[tmplen], writelen - tmplen); } } pmngr->writepos = (pmngr->writepos + writelen) % pmngr->buflen; pmngr->datalen += writelen; CB_GLOBAL_UNLOCK; return writelen; }
void LuaScriptComponent::CreateScriptObject() { LuaStateManager* pStateManager = LuaStateManager::Get(); CB_ASSERT(pStateManager); CB_ASSERT(!m_ScriptObject.IsNil()); LuaPlus::LuaObject metaTableObj = pStateManager->GetGlobalVars().Lookup(LUA_METATABLE_NAME); CB_ASSERT(!metaTableObj.IsNil()); // bind the __object field in lua to this object LuaPlus::LuaObject boxedPtr = pStateManager->GetLuaState()->BoxPointer(this); boxedPtr.SetMetaTable(metaTableObj); m_ScriptObject.SetLightUserData("__object", this); m_ScriptObject.SetMetaTable(metaTableObj); }
void BulletPhysics::Translate(GameObjectId id, const Vec3& vec) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); btVector3 btVec = Vec3_to_btVector3(vec); pRigidBody->translate(btVec); }
HumanView::HumanView(shared_ptr<IRenderer> renderer) { InitAudio(); m_pProcessManager = CB_NEW ProcessManager; m_PointerRadius = 1; m_ViewId = CB_INVALID_GAMEVIEW_ID; RegisterAllDelegates(); m_BaseGameState = BaseGameState::Initializing; if (renderer) { // create the scene graph and camera m_pScene.reset(CB_NEW ScreenElementScene(renderer)); Frustrum frustrum; frustrum.Init(CB_PI / 4.0f, 1.0f, 1.0f, 100.0f); m_pCamera.reset(CB_NEW CameraNode(&Mat4x4::Identity, frustrum)); CB_ASSERT(m_pScene && m_pCamera && L"Out of Memory"); m_pScene->AddChild(INVALID_GAMEOBJECT_ID, m_pCamera); m_pScene->SetCamera(m_pCamera); } m_LastDraw = 0; }
float BulletPhysics::GetOrientationY(GameObjectId id) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); const btTransform& objectTramsform = pRigidBody->getCenterOfMassTransform(); btMatrix3x3 objectRotationMatrix(objectTramsform.getBasis()); btVector3 startingVec(0, 0, 1); btVector3 endingVec = objectRotationMatrix * startingVec; endingVec.setY(0); // we only want the XZ plane const float endingVecLength = endingVec.length(); if (endingVecLength < 0.001) { return 0; } else { btVector3 cross = startingVec.cross(endingVec); float sign = cross.getY() > 0 ? 1.0f : -1.0f; return (acosf(startingVec.dot(endingVec) / endingVecLength) * sign); } // fail case return FLT_MAX; }
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); } } } } }
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::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; }
const Vec3& PathPlan::GetCurrentNodePosition() const { // make sure the current node is valid CB_ASSERT(m_Index != m_Path.end()); // return world position for the current node return (*m_Index)->GetPos(); }
Mat4x4 BulletPhysics::GetTransform(const GameObjectId id) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); const btTransform& objectTransform = pRigidBody->getCenterOfMassTransform(); return btTransform_to_Mat4x4(objectTransform); }
// call the lua callback function with the event void ScriptEventDelegate(IEventPtr pEventPtr) { // make sure its actually a lua function CB_ASSERT(m_ScriptCallbackFunction.IsFunction()); shared_ptr<LuaScriptEvent> pScriptEvent = static_pointer_cast<LuaScriptEvent>(pEventPtr); LuaPlus::LuaFunction<void> Callback = m_ScriptCallbackFunction; Callback(pScriptEvent->GetEventData()); }
/******************************************************************************* ** 函数: cb_read ** 功能: 读取不超过buflen长度的数据到outbuf中, outbuf的长度不得低于buflen ** 返回: 返回实际读取的数据长度, 字节为单位 ** 说明: 如果传入的outbuf地址为NULL, 则直接删除buflen长度的数据 ** 作者: avrbase_lei *******/ static cb_u32 cb_read( CircleBufferMngr *pmngr, cb_u8 *outbuf, cb_u32 buflen) { cb_u32 readlen = 0, tmplen = 0; CB_ASSERT(NULL != pmngr); CB_ASSERT(NULL != pmngr->bufptr); if(cb_empty(pmngr)) return 0; CB_GLOBAL_LOCK; readlen = buflen > pmngr->datalen ? pmngr->datalen : buflen; tmplen = pmngr->buflen - pmngr->readpos; if(NULL != outbuf) { if(readlen <= tmplen) { CB_MEMCPY( (void*)outbuf, (void*)&pmngr->bufptr[pmngr->readpos], readlen); } else { CB_MEMCPY( (void*)outbuf, (void*)&pmngr->bufptr[pmngr->readpos], tmplen); CB_MEMCPY( (void*)&outbuf[tmplen], (void*)pmngr->bufptr, readlen - tmplen); } } pmngr->readpos = (pmngr->readpos + readlen) % pmngr->buflen; pmngr->datalen -= readlen; CB_GLOBAL_UNLOCK; return readlen; }
//==================================================== // PathPlanNode definitions //==================================================== PathPlanNode::PathPlanNode(PathingNode* pNode, PathPlanNode* pPrevNode, PathingNode* pGoalNode) { CB_ASSERT(pNode); m_pPathingNode = pNode; m_pPrev = pPrevNode; m_pGoalNode = pGoalNode; m_Closed = false; UpdateHeuristics(); }
/******************************************************************************* ** 函数: cb_init ** 功能: 初始化 ** 作者: avrbase_lei *******/ static void cb_init(CircleBufferMngr **ppmngr, cb_u32 buflen) { CB_ASSERT(NULL != ppmngr); if (NULL != *ppmngr) return; if (0 == buflen) return; *ppmngr = (CircleBufferMngr*)CB_MALLOC(sizeof(CircleBufferMngr)); CB_ASSERT(NULL != *ppmngr); CB_MEMSET((void*)*ppmngr, 0, sizeof(CircleBufferMngr)); (*ppmngr)->bufptr = (cb_u8*)CB_MALLOC(buflen); CB_ASSERT(NULL != (*ppmngr)->bufptr); (*ppmngr)->buflen = buflen; CB_MEMSET((void*)(*ppmngr)->bufptr, 0, buflen); }
void BulletPhysics::SetAngularVelocity(GameObjectId id, const Vec3& vel) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); if (!pRigidBody) return; btVector3 btVelocity = Vec3_to_btVector3(vel); pRigidBody->setAngularVelocity(btVelocity); }
Vec3 BulletPhysics::GetAngularVelocity(GameObjectId id) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); if (!pRigidBody) return Vec3(); btVector3 btVelocity = pRigidBody->getAngularVelocity(); return btVector3_to_Vec3(btVelocity); }
std::string SkyNode::GetTextureName(const int side) { std::string name = m_TextureBaseName; char* letters[] = { "n", "e", "s", "w", "u" }; unsigned int index = name.find_first_of("_"); CB_ASSERT(index >= 0 && index < name.length() - 1); if (index >= 0 && index < name.length() - 1) { name[index + 1] = *letters[side]; } return name; }
bool RootNode::AddChild(shared_ptr<ISceneNode> child) { // add scene nodes to the correct group off of the root based on its render pass RenderPass pass = child->Get()->GetRenderPass(); if ((unsigned int)pass >= m_Children.size() || !m_Children[pass]) { CB_ASSERT(0 && L"There is no render pass for this node"); return false; } return m_Children[pass]->AddChild(child); }
/******************************************************************************* ** 函数: cb_info ** 功能: 打印管理变量中的各种值到长度为buflen的outbuf中 ** 作者: avrbase_lei *******/ static void cb_info( CircleBufferMngr *pmngr, int (*user_printf)(const char *, ...)) { CB_ASSERT(NULL != pmngr); user_printf( "datalen=%d,readpos=%d,writepos=%d.", pmngr->datalen, pmngr->readpos, pmngr->writepos); }
void BulletPhysics::RotateY(GameObjectId id, float angleRadians, float time) { btRigidBody* pRigidBody = FindBulletRigidBody(id); CB_ASSERT(pRigidBody); btTransform angleTransform; angleTransform.setIdentity(); // rotate about y axis angleTransform.getBasis().setEulerYPR(0, angleRadians, 0); // multiply the transforms pRigidBody->setCenterOfMassTransform(pRigidBody->getCenterOfMassTransform() * angleTransform); }
string InvalidCharsReplacer::fixName(string s) const { CB_ASSERT (string::npos == m_strRenamerReplacementString.find_first_of(m_strRenamerInvalidChars)); if (m_strRenamerInvalidChars.empty()) { return s; } for (;;) { string::size_type n (s.find_first_of(m_strRenamerInvalidChars)); if (string::npos == n) { break; } s.replace(n, 1, m_strRenamerReplacementString); } return s; }
void NetSocket::HandleOutput() { // send all the packets queued to be sent through the socket int fSent = 0; do { CB_ASSERT(!m_OutList.empty()); auto it = m_OutList.begin(); shared_ptr<IPacket> packet = *it; // get the data and sizefrom the current packet const char* buf = packet->GetData(); int len = static_cast<int>(packet->GetSize()); // send the data through the socket, this uses an offset in case a packet // is split and needs to be sent in multiple loop iterations int rc = send(m_Sock, buf + m_SendOffset, len - m_SendOffset, 0); if (rc > 0) { // rc contains number of bytes sent g_pSocketManager->AddToOutbound(rc); m_SendOffset += rc; fSent = 1; } else if (WSAGetLastError() != WSAEWOULDBLOCK) { // if there was an exception HandleException(); fSent = 0; } else { // error or no bytes sent fSent = 0; } // once the entire packet has been sent, pop it from the queue // and reset the offset if (m_SendOffset == packet->GetSize()) { m_OutList.pop_front(); m_SendOffset = 0; } } while (fSent && !m_OutList.empty()); }
/******************************************************************************* ** 函数: cb_deinit ** 功能: 资源释放 ** 作者: avrbase_lei *******/ static void cb_deinit(CircleBufferMngr **ppmngr) { CB_ASSERT(NULL != ppmngr); if(NULL == *ppmngr) return; if (NULL != (*ppmngr)->bufptr) { CB_MFREE((*ppmngr)->bufptr); (*ppmngr)->bufptr = NULL; (*ppmngr)->buflen = 0; } CB_MFREE(*ppmngr); *ppmngr = NULL; }
bool TransformComponent::Init(TiXmlElement* pData) { CB_ASSERT(pData); Vec3 yawPitchRoll = m_Transform.GetYawPitchRoll(); yawPitchRoll.x = RADIANS_TO_DEGREES(yawPitchRoll.x); yawPitchRoll.y = RADIANS_TO_DEGREES(yawPitchRoll.y); yawPitchRoll.z = RADIANS_TO_DEGREES(yawPitchRoll.z); Vec3 position = m_Transform.GetPosition(); TiXmlElement* pPositionElement = pData->FirstChildElement("Position"); if (pPositionElement) { double x = 0; double y = 0; double z = 0; pPositionElement->Attribute("x", &x); pPositionElement->Attribute("y", &y); pPositionElement->Attribute("z", &z); position = Vec3(x, y, z); } TiXmlElement* pOrientationElement = pData->FirstChildElement("YawPitchRoll"); if (pOrientationElement) { double yaw = 0; double pitch = 0; double roll = 0; pOrientationElement->Attribute("x", &yaw); pOrientationElement->Attribute("y", &pitch); pOrientationElement->Attribute("z", &roll); yawPitchRoll = Vec3(yaw, pitch, roll); } Mat4x4 translation; translation.BuildTranslation(position); Mat4x4 rotation; rotation.BuildYawPitchRoll((float)DEGREES_TO_RADIANS(yawPitchRoll.x), (float)DEGREES_TO_RADIANS(yawPitchRoll.y), (float)DEGREES_TO_RADIANS(yawPitchRoll.z)); m_Transform = rotation * translation; return true; }
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>(); }