void CEmiterInstance::DebugRender(CRenderManager* _pRM, const Mat44f& _mTransform, bool _bDebugRenderBoundings) { assert(IsOk()); Mat44f l_mTransform = _mTransform * GetMat44(); _pRM->SetTransform(l_mTransform); if(m_bIsSimple) { if(m_bActive) _pRM->DrawCube(m_vMaxVolume - m_vMinVolume, colGREEN); else _pRM->DrawCube(m_vMaxVolume - m_vMinVolume, colRED); } else { vector<CEmiterInstance*>::iterator l_it = m_ChildEmiters.begin(); vector<CEmiterInstance*>::iterator l_end = m_ChildEmiters.end(); for(; l_it != l_end; ++l_it) { (*l_it)->DebugRender(_pRM, l_mTransform,_bDebugRenderBoundings); } } //_pRM->DrawCube (GetBoundingBox ()->GetMiddlePoint(), GetBoundingBox ()->GetDimension(), colMAGENTA); if(_bDebugRenderBoundings) _pRM->DrawSphere(GetBoundingSphere()->GetMiddlePoint(), GetBoundingSphere()->GetRadius (), colMAGENTA, 10); }
//------------------------------------------------------------ //------------------------------------------------------------ void SpriteComponent::OnRenderSnapshot(RenderSnapshot& in_renderSnapshot) noexcept { Vector2 frameCenter; Vector2 frameSize; if(m_textureAtlas != nullptr && m_hashedTextureAtlasId > 0) { CalcFrameCentreAndSize(frameCenter, frameSize); } else if(mpMaterial != nullptr && mpMaterial->GetTexture() != nullptr) { auto texture = mpMaterial->GetTexture().get(); frameSize = m_sizePolicyDelegate(m_originalSize, Vector2((f32)texture->GetDimensions().x, (f32)texture->GetDimensions().y)); } UVs transformedUVs = m_uvs; if(m_flippedHorizontally == true && m_flippedVertically == true) { transformedUVs = UVs::FlipDiagonally(transformedUVs); } else if(m_flippedHorizontally == true) { transformedUVs = UVs::FlipHorizontally(transformedUVs); } else if(m_flippedVertically == true) { transformedUVs = UVs::FlipVertically(transformedUVs); } const auto& transform = GetEntity()->GetTransform(); auto renderDynamicMesh = SpriteMeshBuilder::Build(in_renderSnapshot.GetFrameAllocator(), Vector3(frameCenter, 0.0f), frameSize, transformedUVs, m_colour, m_originAlignment); auto boundingSphere = Sphere::Transform(renderDynamicMesh->GetBoundingSphere(), transform.GetWorldPosition(), transform.GetWorldScale()); in_renderSnapshot.AddRenderObject(RenderObject(GetMaterial()->GetRenderMaterialGroup(), renderDynamicMesh.get(), transform.GetWorldTransform(), boundingSphere, false, RenderLayer::k_standard)); in_renderSnapshot.AddRenderDynamicMesh(std::move(renderDynamicMesh)); }
void VisibleGameObject::CullDraw(Frustum* pFrustum) { if (pFrustum->Contains(*(GetBoundingSphere()))) { Draw(); } }
int Group::Collide(Solid& moving) const { if (!GetBoundingSphere().Collide(moving.GetBoundingSphere())) return 0; if (!GetBoundingBox().Collide(moving.GetBoundingBox())) return 0; for (int i=0; i < GetCard() ; i++) { Solid* other=group[i]; if (other==&moving) continue; if (!other->GetBoundingSphere().Collide(moving.GetBoundingSphere())) continue; if (!other->GetBoundingBox().Collide(moving.GetBoundingBox())) continue; return 1; } return 0; }
bool ThirdPersonCameraBase::Collision(const Orientation& before, const Orientation& after) { const BoundingSphere& bs = *GetBoundingSphere(); BoundingSphere bsBefore(before.GetVertex(), bs.GetRadius()); BoundingSphere bsAfter(after.GetVertex(), bs.GetRadius()); const WallPoly* pWp = m_heightServer.Intersects(bsBefore, bsAfter); if (pWp) { return true; // We do collide with something } return false; // No collision }
void VisibleGameObject::DrawShadow() const { // NB This relies on us calling RefreshHeightServer(). const BoundingSphere* bs = GetBoundingSphere(); if (!bs) { return; } // Get coords for shadow. const float x = bs->x(); const float y = bs->y(); const float z = bs->z(); m_pShadow->Draw(x, y, z, GetShadowSize(), m_heightServer); }
void SolidComposite::AddHeights(HeightServer* pResult, const BoundingSphere& bs) { // If this composite doesn't intersect the sphere, we are done - no children // intersect it. if (!GetBoundingSphere()->Intersects(bs)) { return; } // Add the HeightServer belonging to each child if the child intersects the // given bounding sphere. for (unsigned int i = 0; i < m_children.size(); i++) { SolidComponent* pc = m_children[i].GetPtr(); Assert(pc); pc->AddHeights(pResult, bs); } }
void SolidLeaf::AddHeights(HeightServer* pResult, const BoundingSphere& bs) { Assert(m_pLeafData); // Do nothing if this geometry isn't solid (collide-able) if (!m_pLeafData->IsSolid()) { return; } // Add the HeightServer belonging to this Leaf if the Leaf intersects the // given bounding sphere. if (GetBoundingSphere()->Intersects(bs)) { // Add the contents of this leaf's HeightServer to the Result HeightServer. pResult->AddHeightServer(m_heightServer); } }
CUmbralModel::CUmbralModel(const ModelChunkPtr& modelChunk) { auto resourceSection = std::dynamic_pointer_cast<CResourceSection>(modelChunk->GetParent()->GetParent()->GetParent()->GetParent()); assert(resourceSection); auto shaderSections = resourceSection->SelectNodes<CShaderSection>(); auto meshNodes = modelChunk->SelectNodes<CMeshChunk>(); assert(!meshNodes.empty()); for(const auto& meshNode : meshNodes) { auto name = meshNode->SelectNode<CStringChunk>(); assert(name); auto shaderSection = FindShaderForName(shaderSections, name->GetString()); auto mesh = std::make_shared<CUmbralMesh>(meshNode, shaderSection); mesh->SetName(name->GetString()); AppendChild(mesh); m_boundingSphere = m_boundingSphere.Accumulate(mesh->GetBoundingSphere()); } }
void FreeMovingSolidGameObject::DrawShadow() const { // Put this in the base class because it is almost certainly more useful // than drawing the shadow whatever the state. if (GetState() != UNKNOWN) { return; } // NB This relies on us calling RefreshHeightServer(). const BoundingSphere* bs = GetBoundingSphere(); if (!bs) { return; } // Get coords for shadow. const float x = bs->x(); const float y = bs->y(); const float z = bs->z(); m_pShadow->Draw(x, y, z, GetShadowSize(), m_heightServer); }
void CUmbralActor::RebuildActorRenderables() { uint32 modelFolder = m_baseModelId % 10000; uint32 modelClass = m_baseModelId / 10000; const char* charaFolder = ""; const char* charaPrefix = ""; switch(modelClass) { case 1: charaFolder = "mon"; charaPrefix = "m"; break; case 2: charaFolder = "bgobj"; charaPrefix = "b"; break; case 4: charaFolder = "wep"; charaPrefix = "w"; break; default: assert(0); break; } uint32 subModelId = m_topModelId >> 10; uint32 variation = m_topModelId & 0x3FF; auto gamePath = CFileManager::GetGamePath(); auto modelPath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_mdl/0001", gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId); Framework::CStdStream inputStream(modelPath.c_str(), "rb"); auto modelResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream); auto modelChunk = modelResource->SelectNode<CModelChunk>(); assert(modelChunk); if(!modelChunk) return; auto boundingBox = modelChunk->SelectNode<CCompChunk>(); CVector3 boxMin(boundingBox->GetMinX(), boundingBox->GetMinY(), boundingBox->GetMinZ()); CVector3 boxMax(boundingBox->GetMaxX(), boundingBox->GetMaxY(), boundingBox->GetMaxZ()); CVector3 modelSize = (boxMax - boxMin) / 2; CVector3 modelPos = (boxMax + boxMin) / 2; auto model = std::make_shared<CUmbralModel>(modelChunk); model->SetPosition(modelPos); model->SetScale(modelSize); AppendChild(model); auto modelBoundingSphere = model->GetBoundingSphere(); modelBoundingSphere.radius *= std::max(std::max(modelSize.x, modelSize.y), modelSize.z); modelBoundingSphere.position += modelPos; m_boundingSphere = modelBoundingSphere; uint32 textureId = 0; if(modelClass == 4) { uint32 varWepId = 1000000000 + (modelFolder * 1000000) + (subModelId * 1000) + variation; auto var = CWeaponVars::GetInstance().GetVarForId(varWepId); textureId = var.textureId; for(const auto& meshNode : model->GetChildren()) { if(auto mesh = std::dynamic_pointer_cast<CUmbralMesh>(meshNode)) { auto meshName = mesh->GetName(); int materialId = 0; if(meshName.find("_a") != std::string::npos) { materialId = 0; } if(meshName.find("_b") != std::string::npos) { materialId = 1; } if(meshName.find("_c") != std::string::npos) { materialId = 2; } if(meshName.find("_d") != std::string::npos) { assert(0); } const auto& varWepMaterial = var.materials[materialId]; auto material = mesh->GetMaterial(); ReplaceMaterialParam(material, "ps_diffuseColor", varWepMaterial.diffuseColor); ReplaceMaterialParam(material, "ps_multiDiffuseColor", varWepMaterial.multiDiffuseColor); ReplaceMaterialParam(material, "ps_specularColor", varWepMaterial.specularColor); ReplaceMaterialParam(material, "ps_multiSpecularColor", varWepMaterial.multiSpecularColor); ReplaceMaterialParam(material, "ps_reflectivity", varWepMaterial.specularColor); ReplaceMaterialParam(material, "ps_multiReflectivity", varWepMaterial.multiSpecularColor); ReplaceMaterialParam(material, "ps_shininess", varWepMaterial.shininess); ReplaceMaterialParam(material, "ps_multiShininess", varWepMaterial.multiShininess); mesh->SetActivePolyGroups(var.polyGroupState); } } } { auto texturePath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_tex2/%0.4d", gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId, textureId); Framework::CStdStream inputStream(texturePath.c_str(), "rb"); auto textureResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream); model->SetLocalTexture(textureResource); } m_renderableDirty = false; }
void BoundingSphere(Vector<T, 4>& center_and_radius) const { center_and_radius = Vector<T, 4>(GetBoundingSphere()); }
void BoundingSphere(oglplus::Sphere<T>& bounding_sphere) const { bounding_sphere = oglplus::Sphere<T>(GetBoundingSphere()); }
const BoundingSphere* VisibleGameObject::GetHeightServerSphere() { return GetBoundingSphere(); }
void ThirdPersonCameraBase::RefreshHeightServer(Level* pLevel) { m_heightServer.Clear(); pLevel->GetHeightServer(&m_heightServer, *GetBoundingSphere()); }
void CActorInstance::RenderCollisionData() { static CScreen s_Screen; STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE); STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); if (m_pAttributeInstance) { for (DWORD col=0; col < GetCollisionInstanceCount(); ++col) { CBaseCollisionInstance * pInstance = GetCollisionInstanceData(col); pInstance->Render(); } } STATEMANAGER.SetRenderState(D3DRS_ZENABLE, FALSE); s_Screen.SetColorOperation(); s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f); TCollisionPointInstanceList::iterator itor; /*itor = m_AttackingPointInstanceList.begin(); for (; itor != m_AttackingPointInstanceList.end(); ++itor) { const TCollisionPointInstance & c_rInstance = *itor; for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) { const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, c_rSphereInstance.v3Position.y, c_rSphereInstance.v3Position.z, c_rSphereInstance.fRadius); } }*/ s_Screen.SetDiffuseColor(1.0f, (isShow())?1.0f:0.0f, 0.0f); D3DXVECTOR3 center; float r; GetBoundingSphere(center,r); s_Screen.RenderCircle3d(center.x,center.y,center.z,r); s_Screen.SetDiffuseColor(0.0f, 0.0f, 1.0f); itor = m_DefendingPointInstanceList.begin(); for (; itor != m_DefendingPointInstanceList.end(); ++itor) { const TCollisionPointInstance & c_rInstance = *itor; for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) { const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, c_rSphereInstance.v3Position.y, c_rSphereInstance.v3Position.z, c_rSphereInstance.fRadius); } } s_Screen.SetDiffuseColor(0.0f, 1.0f, 0.0f); itor = m_BodyPointInstanceList.begin(); for (; itor != m_BodyPointInstanceList.end(); ++itor) { const TCollisionPointInstance & c_rInstance = *itor; for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i) { const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i]; s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x, c_rSphereInstance.v3Position.y, c_rSphereInstance.v3Position.z, c_rSphereInstance.fRadius); } } s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f); // if (m_SplashArea.fDisappearingTime > GetLocalTime()) { CDynamicSphereInstanceVector::iterator itor = m_kSplashArea.SphereInstanceVector.begin(); for (; itor != m_kSplashArea.SphereInstanceVector.end(); ++itor) { const CDynamicSphereInstance & c_rInstance = *itor; s_Screen.RenderCircle3d(c_rInstance.v3Position.x, c_rInstance.v3Position.y, c_rInstance.v3Position.z, c_rInstance.fRadius); } } STATEMANAGER.SetRenderState(D3DRS_ZENABLE, TRUE); STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE); }
void CEmiterInstance::Update(float _fDeltaTime) { assert(IsOk()); if(!m_bActive) return; if(!m_pInRoom->GetNeightbour()) return; //mirem si el delta time és massa gran, per no fer actualitzacions massa a saco, les capem a un min de framerate if(_fDeltaTime > MAX_PARTICLE_DELTA_TIME) _fDeltaTime = MAX_PARTICLE_DELTA_TIME; if(m_pObjectReference) { //l_mTransform = _mTransform * m_pObjectReference->GetMat44(); Mat44f m = m_pObjectReference->GetMat44(); m = m * m_ObjectOffset.GetMat44(); SetMat44(m); //l_mTransform = l_mTransform * GetMat44(); } bool l_bBBModified = false; if(m_bBillboardMode) { CRenderManager* l_pRM = CORE->GetRenderManager(); SParticleRenderInfo* l_pInstanceBuffer = m_InstancedData.GetBuffer(1, l_pRM); assert(l_pInstanceBuffer); m_Billboard.Update(_fDeltaTime); m_Billboard.FillRenderInfo(l_pInstanceBuffer[0]); bool l_bResult = m_InstancedData.SetData(l_pInstanceBuffer, 1, l_pRM); assert(l_bResult); }else if(m_bIsSimple) { CRenderManager* l_pRM = CORE->GetRenderManager(); SParticleRenderInfo* l_pInstanceBuffer = m_InstancedData.GetBuffer(m_iMaxParticles, l_pRM); assert(l_pInstanceBuffer); const CSimpleEmiterCore *l_pEmiterCore = dynamic_cast<const CSimpleEmiterCore*>(m_pEmiterCore); //actualitzem les partícules for(int i = 0; i < m_iActiveParticles; ++i) { CParticle* l_pParticle = m_RecyclingParticles.GetAt(m_iaParticles[i]); if(l_pParticle->Update(_fDeltaTime)) { //la partícula encara està viva, omplim la informació al buffer de rendetizatge. l_pParticle->FillRenderInfo(l_pInstanceBuffer[i]); l_bBBModified = GetBoundingBox()->Adjust(l_pParticle->GetPosition()) | l_bBBModified; } else { m_RecyclingParticles.Free(m_iaParticles[i]); m_iActiveParticles--; m_iaParticles[i] = m_iaParticles[m_iActiveParticles]; if(i != m_iActiveParticles) --i; } } m_fTimeToAwakeOrSleep -= _fDeltaTime; while(m_fTimeToAwakeOrSleep <= 0) { m_bAwake = !m_bAwake; if(m_bAwake) { m_fTimeToAwakeOrSleep += l_pEmiterCore->GetAwakeTime(); } else { m_fTimeToAwakeOrSleep += l_pEmiterCore->GetSleepTime(); } } // si ha passat prou temps com per crear una partícula nova while(_fDeltaTime > m_fTimeToNextParticle) { _fDeltaTime -= m_fTimeToNextParticle; float l_fMultiplier = l_pEmiterCore->GetEmitAbsolute()? 1 : m_fVolume; m_fTimeToNextParticle = 1.f / (l_pEmiterCore->GetEmitRate() * l_fMultiplier); //carreguem el temps fins la següent partícula if(m_bAwake && m_iActiveParticles < m_iMaxParticles) //comprovem que el buffer no hagi quedat ple { int l_iParticle = m_RecyclingParticles.NewIndex(); //agafem una partícula del buffer CParticle* l_pParticle = m_RecyclingParticles.GetAt(l_iParticle); //creem la partícula dintre de la caixa inicial Vect3f l_vRnd(Random01(),Random01(),Random01()); Vect3f l_v_1_Minus_Rnd(1.f - l_vRnd.x, 1.f - l_vRnd.y, 1.f - l_vRnd.z); Vect3f l_vInitialPosition = ( l_v_1_Minus_Rnd.Scale(m_vMinVolume) ) + ( l_vRnd.Scale(m_vMaxVolume) ); //inicialitzem la partícula l_pParticle->Init(l_pEmiterCore, l_vInitialPosition, false); m_iaParticles[m_iActiveParticles] = l_iParticle; //actualitzem aquesta partícula fins al final d'aquest frame if(l_pParticle->Update(_fDeltaTime)) { //la partícula encara està viva, omplim la informació al buffer de rendetizatge. l_pParticle->FillRenderInfo(l_pInstanceBuffer[m_iActiveParticles]); l_bBBModified = GetBoundingBox()->Adjust(l_pParticle->GetPosition()) | l_bBBModified; } else { m_RecyclingParticles.Free(m_iaParticles[m_iActiveParticles]); m_iActiveParticles--; } m_iActiveParticles++; } else { m_fTimeToNextParticle = _fDeltaTime; break; } } m_fTimeToNextParticle -= _fDeltaTime; bool l_bResult = m_InstancedData.SetData(l_pInstanceBuffer, m_iActiveParticles, l_pRM); assert(l_bResult); } else { vector<CEmiterInstance*>::iterator l_it = m_ChildEmiters.begin(); vector<CEmiterInstance*>::iterator l_end = m_ChildEmiters.end(); for(; l_it != l_end; ++l_it) { (*l_it)->Update(_fDeltaTime); l_bBBModified = GetBoundingBox()->Adjust(*(*l_it)->GetBoundingBox()) | l_bBBModified; } } if(l_bBBModified) { GetBoundingSphere()->Init(*GetBoundingBox()); } }
bool CEmiterInstance::Init(const string& _szCoreName, const CObject3D& _Position, const Vect3f& _vVolume, int _iMaxParticles, bool _bBillboardMode ) { assert(!IsOk()); SetOk(true); SetMat44( _Position.GetMat44() ); m_szCoreName = _szCoreName; m_vVolume = _vVolume; m_vMaxVolume = m_vVolume * .5f; m_vMinVolume = -m_vMaxVolume; m_fVolume = _vVolume.x * _vVolume.y * _vVolume.z; m_pEmiterCore = CORE->GetEmiterCoreManager()->GetEmiterCore(m_szCoreName); m_bBillboardMode = _bBillboardMode; m_iMaxParticles = _iMaxParticles; m_RecyclingParticles.Reset(m_iMaxParticles); m_iaParticles = new int[m_iMaxParticles]; GetBoundingBox()->Init(_vVolume); if(m_bBillboardMode) { if(m_pEmiterCore->IsSimpleEmiter()) { m_Billboard.Init(dynamic_cast<const CSimpleEmiterCore*>(m_pEmiterCore), Vect3f(0,0,0),true); } else { LOGGER->AddNewLog(ELL_WARNING, "Trying to initialize billboard with aggregate emiter."); m_pEmiterCore = CORE->GetEmiterCoreManager()->GetNullEmiter(); m_Billboard.Init(CORE->GetEmiterCoreManager()->GetNullEmiter(), Vect3f(0,0,0),true); } } else if(m_pEmiterCore->IsSimpleEmiter()) { m_bIsSimple = true; const CSimpleEmiterCore *l_pEmiterCore = dynamic_cast<const CSimpleEmiterCore*>(m_pEmiterCore); float l_fMultiplier = l_pEmiterCore->GetEmitAbsolute()? 1 : m_fVolume; m_fTimeToNextParticle = 1.f / (l_pEmiterCore->GetEmitRate() * l_fMultiplier); m_iActiveParticles = 0; memset(m_iaParticles, 0, sizeof(int) * m_iMaxParticles); m_bAwake = true; m_fTimeToAwakeOrSleep = l_pEmiterCore->GetAwakeTime(); m_pObjectReference = 0; m_bActive = true; } else { m_bIsSimple = false; const CAggregateEmiterCore *l_pEmiterCore = dynamic_cast<const CAggregateEmiterCore*>(m_pEmiterCore); vector<CAggregateEmiterCore::SEmiters>::const_iterator l_it = l_pEmiterCore->GetChilds().begin(); vector<CAggregateEmiterCore::SEmiters>::const_iterator l_end = l_pEmiterCore->GetChilds().end(); for(; l_it != l_end; ++l_it) { CEmiterInstance *l_pChild = new CEmiterInstance(); Vect3f l_vChildBox = l_it->volume.GetScaled(_vVolume); //Mat44f l_mChildTransform = Mat44f(_vVolume.x, 0, 0, 0, // 0, _vVolume.y, 0, 0, // 0, 0, _vVolume.z, 0, // 0, 0, 0, 1) // * l_it->movement.GetMat44(); //CObject3D l_O3D; //l_O3D.SetMat44(l_mChildTransform); Mat44f l_mChildTransform = l_it->movement.GetMat44(); Vect3f l_vChildTranslation = l_mChildTransform.GetTranslationVector(); l_vChildTranslation.Scale(_vVolume); l_mChildTransform.Translate(l_vChildTranslation); CObject3D l_O3D; l_O3D.SetMat44(l_mChildTransform); bool l_bIsOk = l_pChild->Init(l_it->emiter, l_O3D, l_vChildBox); if(l_bIsOk) { m_ChildEmiters.push_back(l_pChild); GetBoundingBox()->Adjust(*l_pChild->GetBoundingBox()); } else { delete l_pChild; SetOk(false); break; } } } if(!IsOk()) { Release(); } else if(!m_InstancedData.IsOk()) { bool l_bIsOk = m_InstancedData.Init(CORE->GetRenderManager(), m_iMaxParticles); SetOk(l_bIsOk); } GetBoundingSphere()->Init(*GetBoundingBox()); if(IsOk()) CORE->GetPortalManager()->InsertEmiter(this); return IsOk(); }