void ESceneObjectTools::GetStaticDesc(int& v_cnt, int& f_cnt) { for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ CSceneObject* obj = (CSceneObject*)(*it); if (obj->IsStatic()){ f_cnt += obj->GetFaceCount(); v_cnt += obj->GetVertexCount(); } } }
bool SceneBuilder::BuildSOMModel() { BOOL bResult = TRUE; CMemoryWriter F; F.open_chunk (0); F.w_u32 (0); F.close_chunk (); F.open_chunk (1); ObjectList& lst = Scene->ListObj(OBJCLASS_SCENEOBJECT); for (ObjectIt it=lst.begin(); it!=lst.end(); it++){ CSceneObject* S = (CSceneObject*)(*it); CEditableObject* E = S->GetReference(); R_ASSERT(E); if (E->m_Flags.is(CEditableObject::eoSoundOccluder)){ Fvector v; const Fmatrix& parent = S->_Transform(); for (EditMeshIt m_it=E->FirstMesh(); m_it!=E->LastMesh(); m_it++){ for (SurfFacesPairIt sf_it=(*m_it)->m_SurfFaces.begin(); sf_it!=(*m_it)->m_SurfFaces.end(); sf_it++){ CSurface* surf = sf_it->first; int gm_id = surf->_GameMtl(); if (gm_id==GAMEMTL_NONE_ID){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain invalid game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } SGameMtl* mtl = GMLib.GetMaterialByID(gm_id); if (0==mtl){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain undefined game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } BOOL b2Sided = surf->m_Flags.is(CSurface::sf2Sided); IntVec& i_lst = sf_it->second; for (IntIt i_it=i_lst.begin(); i_it!=i_lst.end(); i_it++){ st_Face& face = (*m_it)->m_Faces[*i_it]; for (int k=0; k<3; k++){ parent.transform_tiny(v,(*m_it)->m_Verts[face.pv[k].pindex]); F.w_fvector3(v); } F.w_u32 (b2Sided); F.w_float (mtl->fSndOcclusionFactor); } } } } } BOOL bValid = !!F.chunk_size()&&bResult; F.close_chunk(); if (bValid){ xr_string som_name = MakeLevelPath("level.som"); bValid = F.save_to(som_name.c_str()); } return bValid; }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function Name: CheckCorkableAABB() // Purpose: Check for collision and react appropriately // Original Author: Rueben Massey // Creation Date: 6/13/2012 // Last Modification By: // Last Modification Date: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CComponent_IntakePipeCollision::CheckCorkableAABB( float fDT ) { // create a return vector to hold all the objects the kd tree returns std::vector <CSceneObject*> NearestObjects; // create a unsigned int that will tell the kd tree what you want put in the return vector // this uses bit wise operations so you can have more then one object returned // use the return flags enum from the kd tree so you know what you can get back int ReturnParams = 0; int ReturnBody = 0; int ReturnObjects = (1<<OBJ_CORK); CSceneObject intakeAABB; intakeAABB.SetCollidableObject( &m_abTarget ); // call the kd tree and get the near objects // call the kd tree and get the near objects CKdTree::GetNearObjects ( &intakeAABB, PSFLAG_AABB, ReturnParams, NearestObjects, ReturnBody, ReturnObjects ); //intakeAABB.SetCollidableObject( NULL ); vec2f Direction; vec2f CP; for( unsigned int objindex = 0; objindex < NearestObjects.size(); ++objindex ) { // get the collision component of the object CComponent_Collision* curCollision = (CComponent_Collision*)(((IBaseObject*)NearestObjects[objindex]))->GetComponent (ECOMP_COLLISION); // get the collision volume of the object CCollisionVolume* curVolume = NearestObjects[objindex]->GetCollidableObject(); // Safety Check if( curVolume && curCollision && curCollision != this ) { if( m_bCorked ) { break; } // We have collided // Do stuff to the object if( ((Box*)curVolume)->BoxToAABB( m_abTarget, CP, Direction ) ) { // We have collided // get the plug's collision component // so we can move it m_pCork = curCollision; // set this flag // so we can move the plug // in update m_bIsGettingCorked = true; } } } }
//BOOL GetMuStaticCformData( CSceneObject* obj,mesh_build_data &data, bool b_selected_only ); BOOL GetStaticCformData ( ObjectList& lst, mesh_build_data &data, bool b_selected_only ) { BOOL bResult = TRUE; for(ObjectIt _F = lst.begin();_F!=lst.end();_F++) { // pb->Inc((*_F)->Name); // if (UI->NeedAbort()) break; if(b_selected_only && !(*_F)->Selected()) continue; switch((*_F)->ClassID){ // case OBJCLASS_LIGHT: // bResult = BuildLight((CLight*)(*_F)); // break; // case OBJCLASS_GLOW: // bResult = BuildGlow((CGlow*)(*_F)); // break; /// case OBJCLASS_PORTAL: // l_portals.push_back(b_portal()); // BuildPortal(&l_portals.back(),(CPortal*)(*_F)); // break; case OBJCLASS_SCENEOBJECT:{ CSceneObject *obj = (CSceneObject*)(*_F); if (obj->IsStatic()) bResult = GetStaticCformData(obj,data,b_selected_only); else if (obj->IsMUStatic()) bResult = GetStaticCformData(obj,data,b_selected_only); }break; /* case OBJCLASS_GROUP:{ CGroupObject* group = (CGroupObject*)(*_F); ObjectList grp_lst; group->GetObjects (grp_lst); bResult = ParseStaticObjects(grp_lst, group->Name, b_selected_only); }break; */ }// end switch } // UI->ProgressEnd(pb); return bResult; }
//---------------------------------------------------- // some types bool SceneBuilder::BuildHOMModel() { CMemoryWriter F; F.open_chunk(0); F.w_u32(0); F.close_chunk(); F.open_chunk(1); ObjectList& lst = Scene->ListObj(OBJCLASS_SCENEOBJECT); for (ObjectIt it=lst.begin(); it!=lst.end(); it++){ CSceneObject* S = (CSceneObject*)(*it); CEditableObject* E = S->GetReference(); R_ASSERT(E); if (E->m_Flags.is(CEditableObject::eoHOM)){ Fvector v; const Fmatrix& parent = S->_Transform(); for (EditMeshIt m_it=E->FirstMesh(); m_it!=E->LastMesh(); m_it++){ for (SurfFacesPairIt sf_it=(*m_it)->m_SurfFaces.begin(); sf_it!=(*m_it)->m_SurfFaces.end(); sf_it++){ BOOL b2Sided = sf_it->first->m_Flags.is(CSurface::sf2Sided); IntVec& i_lst= sf_it->second; for (IntIt i_it=i_lst.begin(); i_it!=i_lst.end(); i_it++){ st_Face& face = (*m_it)->m_Faces[*i_it]; for (int k=0; k<3; k++){ parent.transform_tiny(v,(*m_it)->m_Verts[face.pv[k].pindex]); F.w_fvector3 (v); } F.w_u32(b2Sided); } } } } } BOOL bValid = !!F.chunk_size(); F.close_chunk(); if (bValid){ xr_string hom_name = MakeLevelPath("level.hom"); bValid = F.save_to(hom_name.c_str()); } return bValid; }
// this function is obsoleted, use ParaMovie::TakeScreenShot3 instead. bool ParaMovie::RenderToTexture(const char* filename, int width, int height) { // code no longer used. it just provides an example of calling render to texture. #if 0 //#include "AutoCamera.h" //#include "SceneObject.h" //#include "FrameRateController.h" LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice(); if(pd3dDevice == 0) return false; CSceneObject* pScene = CGlobals::GetScene(); LPDIRECT3DTEXTURE9 m_pRenderTarget = NULL; LPDIRECT3DSURFACE9 m_pRenderTargetSurface = NULL; LPDIRECT3DSURFACE9 m_pDepthSurface = NULL; D3DVIEWPORT9 oldViewport; D3DFORMAT colorFormat = D3DFMT_A8R8G8B8; D3DFORMAT zFormat = D3DFMT_D24S8; // render the scene if( SUCCEEDED( pd3dDevice->BeginScene() ) ) { if(FAILED(pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, colorFormat, D3DPOOL_DEFAULT, &m_pRenderTarget, NULL))) return false; if(FAILED(m_pRenderTarget->GetSurfaceLevel(0, &m_pRenderTargetSurface))) return false; if(FAILED(pd3dDevice->CreateDepthStencilSurface(width, height, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, FALSE, &m_pDepthSurface, NULL))) return false; ////////////////////////////////////////////////////////////////////////// // Render to the reflection map LPDIRECT3DSURFACE9 pOldRenderTarget = CGlobals::GetDirectXEngine().GetRenderTarget(); CGlobals::GetDirectXEngine().SetRenderTarget(0, m_pRenderTargetSurface); CBaseCamera* pCamera = pScene->GetCurrentCamera(); float fOldAspectRatio = pCamera->GetAspectRatio(); pCamera->SetAspectRatio((float)width/(float)height); pd3dDevice->GetViewport(&oldViewport); D3DVIEWPORT9 newViewport; newViewport.X = 0; newViewport.Y = 0; newViewport.Width = width; newViewport.Height = height; newViewport.MinZ = 0.0f; newViewport.MaxZ = 1.0f; pd3dDevice->SetViewport(&newViewport); // set depth surface LPDIRECT3DSURFACE9 pOldZBuffer = NULL; if(FAILED(pd3dDevice->GetDepthStencilSurface(&pOldZBuffer))) { OUTPUT_LOG("GetDepthStencilSurface failed\r\n"); return false; } pd3dDevice->SetDepthStencilSurface( m_pDepthSurface ); ///////////////////////////////////////////////////////////////////////// /// render /// clear to scene pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ); if(pScene->IsSceneEnabled()) { ///-- set up effects parameters ((CAutoCamera*)pCamera)->UpdateViewProjMatrix(); pScene->AdvanceScene(0); } ////////////////////////////////////////////////////////////////////////// // Restore to old settings D3DXIMAGE_FILEFORMAT FileFormat = D3DXIFF_JPG; D3DXSaveTextureToFile(filename, FileFormat, m_pRenderTarget, NULL); // restore old view port pd3dDevice->SetViewport(&oldViewport); pCamera->SetAspectRatio(fOldAspectRatio); pd3dDevice->SetDepthStencilSurface( pOldZBuffer); SAFE_RELEASE(pOldZBuffer); CGlobals::GetDirectXEngine().SetRenderTarget(0, pOldRenderTarget); SAFE_RELEASE(m_pRenderTargetSurface); SAFE_RELEASE(m_pDepthSurface); SAFE_RELEASE(m_pRenderTarget); pd3dDevice->EndScene(); } #endif return true; }
bool ESceneObjectTool::ExportBreakableObjects(SExportStreams* F) { bool bResult = true; CGeomPartExtractor* extractor=0; Fbox bb; if (!GetBox(bb)) return false; extractor = xr_new<CGeomPartExtractor>(); extractor->Initialize(bb,EPS_L,2); UI->SetStatus ("Export breakable objects..."); // collect verts&&faces { SPBItem* pb = UI->ProgressStart(m_Objects.size(),"Prepare geometry..."); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ pb->Inc(); CSceneObject* obj = dynamic_cast<CSceneObject*>(*it); VERIFY(obj); if (obj->IsStatic()){ CEditableObject *O = obj->GetReference(); const Fmatrix& T = obj->_Transform(); for(EditMeshIt M=O->FirstMesh();M!=O->LastMesh();M++) if (!build_mesh (T,*M,extractor,SGameMtl::flBreakable,FALSE)){bResult=false;break;} } } UI->ProgressEnd(pb); } if (!extractor->Process()) bResult = false; // export parts if (bResult){ SBPartVec& parts = extractor->GetParts(); SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts..."); for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++){ pb->Inc(); SBPart* P = *p_it; if (P->Valid()){ // export visual AnsiString sn = AnsiString().sprintf("meshes\\brkbl#%d.ogf",(p_it-parts.begin())); xr_string fn = Scene->LevelPath()+sn.c_str(); IWriter* W = FS.w_open(fn.c_str()); R_ASSERT(W); if (!P->Export(*W,1)){ ELog.DlgMsg (mtError,"Invalid breakable object."); bResult = false; break; } FS.w_close (W); // export spawn object { AnsiString entity_ref = "breakable_object"; ISE_Abstract* m_Data = create_entity(entity_ref.c_str()); VERIFY(m_Data); CSE_Visual* m_Visual = m_Data->visual(); VERIFY(m_Visual); // set params m_Data->set_name (entity_ref.c_str()); m_Data->set_name_replace (sn.c_str()); m_Data->position().set (P->m_RefOffset); m_Data->angle().set (P->m_RefRotate); m_Visual->set_visual (sn.c_str(),false); if (s_draw_dbg){ Fmatrix MX; MX.setXYZi (P->m_RefRotate); MX.translate_over (P->m_RefOffset); Fvector DR = {0,0,1}; MX.transform_dir (DR); Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,MX.k,1.f),0xFF0000FF,false,false); } NET_Packet Packet; m_Data->Spawn_Write (Packet,TRUE); F->spawn.stream.open_chunk (F->spawn.chunk++); F->spawn.stream.w (Packet.B.data,Packet.B.count); F->spawn.stream.close_chunk (); destroy_entity (m_Data); } }else{ ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin()); } } UI->ProgressEnd(pb); } // clean up xr_delete(extractor); return bResult; }
bool ESceneObjectTool::ExportClimableObjects(SExportStreams* F) { bool bResult = true; CGeomPartExtractor* extractor = 0; Fbox bb; if (!GetBox(bb)) return false; extractor = xr_new<CGeomPartExtractor>(); extractor->Initialize (bb,EPS_L,int_max); UI->SetStatus ("Export climable objects..."); // collect verts&&faces { SPBItem* pb = UI->ProgressStart(m_Objects.size(), "Prepare geometry..."); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++) { pb->Inc(); CSceneObject* obj = dynamic_cast<CSceneObject*>(*it); VERIFY (obj); if (obj->IsStatic()) { CEditableObject *O = obj->GetReference(); const Fmatrix& T = obj->_Transform(); for(EditMeshIt M =O->FirstMesh(); M!=O->LastMesh(); M++) if (!build_mesh (T, *M, extractor, SGameMtl::flClimable, TRUE)) { bResult = false; break; } } } UI->ProgressEnd(pb); } if (!extractor->Process()) bResult = false; // export parts if (bResult) { SBPartVec& parts = extractor->GetParts(); SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts..."); for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++) { pb->Inc (); SBPart* P = *p_it; if (P->Valid()) { // export visual AnsiString sn = AnsiString().sprintf("clmbl#%d",(p_it-parts.begin())); Fvector local_normal = {0,0,0}; LPCSTR mat_name = NULL; for (SBFaceVecIt it=P->m_Faces.begin(); it!=P->m_Faces.end(); it++) { for (u32 k=0; k<3; k++) local_normal.add ((*it)->n[k]); mat_name = (*it)->surf->_GameMtlName(); } local_normal.normalize_safe (); // export spawn object { AnsiString entity_ref = "climable_object"; ISE_Abstract* m_Data = create_entity(entity_ref.c_str()); VERIFY(m_Data); ISE_Shape* m_Shape = m_Data->shape(); VERIFY(m_Shape); // CSE_Visual* m_Visual = m_Data->visual(); VERIFY(m_Visual); // set params m_Data->set_name (entity_ref.c_str()); m_Data->set_name_replace (sn.c_str()); // set shape CShapeData::shape_def shape; shape.type = CShapeData::cfBox; shape.data.box.scale ((P->m_BBox.max.x-P->m_BBox.min.x)*0.5f, (P->m_BBox.max.y-P->m_BBox.min.y)*0.5f, (P->m_BBox.max.z-P->m_BBox.min.z)*0.5f); m_Shape->assign_shapes (&shape,1); // orientate object if (!OrientToNorm(local_normal,P->m_OBB.m_rotate,P->m_OBB.m_halfsize)) { ELog.Msg(mtError,"Invalid climable object found. [%3.2f, %3.2f, %3.2f]",VPUSH(P->m_RefOffset)); } else { Fmatrix M; M.set (P->m_OBB.m_rotate.i,P->m_OBB.m_rotate.j,P->m_OBB.m_rotate.k,P->m_OBB.m_translate); M.getXYZ (P->m_RefRotate); // не i потому что в движке так m_Data->position().set (P->m_RefOffset); m_Data->angle().set (P->m_RefRotate); m_Data->set_additional_info((void*)mat_name); NET_Packet Packet; m_Data->Spawn_Write (Packet,TRUE); F->spawn.stream.open_chunk (F->spawn.chunk++); F->spawn.stream.w (Packet.B.data,Packet.B.count); F->spawn.stream.close_chunk (); if (s_draw_dbg) { Tools->m_DebugDraw.AppendOBB(P->m_OBB); M.transform_dir (local_normal); Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,local_normal,1.f)); } } destroy_entity (m_Data); } }else { ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin()); } } UI->ProgressEnd (pb); } // clean up xr_delete (extractor); return bResult; }
bool ESceneAIMapTool::GenerateMap(bool bFromSelectedOnly) { std::sort(m_ignored_materials.begin(),m_ignored_materials.end()); bool bRes = false; if (!GetSnapList()->empty()){ if (!RealUpdateSnapList()) return false; if (m_Nodes.empty()){ ELog.DlgMsg(mtError,"Append at least one node."); return false; } if (!m_Flags.is(flSlowCalculate)){ // evict resources ExecCommand (COMMAND_EVICT_OBJECTS); ExecCommand (COMMAND_EVICT_TEXTURES); // prepare collision model u32 avg_face_cnt = 0; u32 avg_vert_cnt = 0; u32 mesh_cnt = 0; Fbox snap_bb; { snap_bb.invalidate (); for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++){ CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); avg_face_cnt += S->GetFaceCount(); avg_vert_cnt += S->GetVertexCount(); mesh_cnt += S->Meshes()->size(); Fbox bb; S->GetBox (bb); snap_bb.merge (bb); } } SPBItem* pb = UI->ProgressStart(mesh_cnt,"Prepare collision model..."); CDB::Collector* CL = ETOOLS::create_collector(); Fvector verts[3]; for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++) { CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); CEditableObject* E = S->GetReference(); VERIFY(E); EditMeshVec& _meshes = E->Meshes(); for (EditMeshIt m_it=_meshes.begin(); m_it!=_meshes.end(); m_it++) { pb->Inc(AnsiString().sprintf("%s [%s]",S->Name,(*m_it)->Name().c_str()).c_str()); const SurfFaces& _sfaces = (*m_it)->GetSurfFaces(); for (SurfFaces::const_iterator sp_it=_sfaces.begin(); sp_it!=_sfaces.end(); sp_it++) { CSurface* surf = sp_it->first; // test passable //. SGameMtl* mtl = GMLib.GetMaterialByID(surf->_GameMtl()); //. if (mtl->Flags.is(SGameMtl::flPassable))continue; Shader_xrLC* c_sh = Device.ShaderXRLC.Get(surf->_ShaderXRLCName()); if (!c_sh->flags.bCollision) continue; // collect tris const IntVec& face_lst = sp_it->second; for (IntVec::const_iterator it=face_lst.begin(); it!=face_lst.end(); it++) { E->GetFaceWorld (S->_Transform(),*m_it,*it,verts); ETOOLS::collector_add_face_d(CL,verts[0],verts[1],verts[2], surf->_GameMtl() /* *it */); if (surf->m_Flags.is(CSurface::sf2Sided)) ETOOLS::collector_add_face_d(CL,verts[2],verts[1],verts[0], surf->_GameMtl() /* *it */); } } } } UI->ProgressEnd(pb); UI->SetStatus ("Building collision model..."); // create CFModel m_CFModel = ETOOLS::create_model_cl(CL); ETOOLS::destroy_collector(CL); } // building Scene->lock (); CTimer tm; tm.Start(); BuildNodes (bFromSelectedOnly); tm.GetElapsed_sec(); Scene->unlock (); //. Log("-test time: ", g_tm.GetElapsed_sec()); Log("-building time: ",tm.GetElapsed_sec()); //. Msg("-Rate: %3.2f Count: %d",(g_tm.GetElapsed_sec()/tm.GetElapsed_sec())*100.f,g_tm.count); // unload CFModel ETOOLS::destroy_model(m_CFModel); Scene->UndoSave (); bRes = true; UI->SetStatus (""); }else{ ELog.DlgMsg(mtError,"Fill snap list before generating slots!"); } return bRes; }
void CEnvironmentSim::Simulate(double dTimeDelta) { if(dTimeDelta<=0) return; CSceneObject* pScene = CGlobals::GetScene(); if((pScene == NULL) || pScene->IsScenePaused() || (!(pScene->IsSceneEnabled())) ) return; // physics engine frame move. CGlobals::GetPhysicsWorld()->StepSimulation(dTimeDelta); /** advance the game time */ g_gameTime.FrameMoveDelta((float)dTimeDelta); // advance time of day pScene->GetSunLight().AdvanceTimeOfDay((float)dTimeDelta); /** Check load physics around the current player and the camera position * this is very game specific. It only ensures that physics object around the current player and camera is loaded. */ CBipedObject* pPlayer = pScene->GetCurrentPlayer(); int nPointCount = 0; CShapeSphere points[2]; if(pPlayer) { points[nPointCount].Set(pPlayer->GetPosition(), pPlayer->GetPhysicsRadius()*2.f); nPointCount++; } if(pScene->GetCurrentCamera()) { points[nPointCount].Set(pScene->GetCurrentCamera()->GetEyePosition(), pScene->GetCurrentCamera()->GetNearPlane()*2); nPointCount++; } CheckLoadPhysics(points, nPointCount); UpdateGameObjects(dTimeDelta); { PERF1("EnvSim::Frame Move Sentient Objects"); for (auto itCur = pScene->GetSentientObjects().begin(); itCur != pScene->GetSentientObjects().end();) { IGameObject* pObj = (*itCur); if (!pObj) { itCur = pScene->GetSentientObjects().erase(itCur); OUTPUT_LOG("warn: invalid weak ref found in pScene->GetSentientObjects()\n"); continue; } else { itCur++; } if(pObj->GetSimTag() != SIM_TAG_FINISHED) { pScene->SetCurrentActor((CBaseObject*)pObj); if(pObj->GetSimTag() == SIM_TAG_START) { // generate way points pObj->PathFinding(dTimeDelta); // move the biped according to way point commands pObj->AnimateBiped(dTimeDelta); } // apply AI controller if(pObj->GetAIModule()) pObj->GetAIModule()->FrameMove((float)dTimeDelta); if(!pObj->GetPerceiveList().empty()) pObj->On_Perception(); // call the frame move script if any. pObj->On_FrameMove(); pObj->SetSimTag(SIM_TAG_FINISHED); if(pObj->HasReferences()) { RefList::iterator itCur, itEnd = pObj->GetRefList().end(); for (itCur = pObj->GetRefList().begin(); itCur!=itEnd; ++itCur) { if(itCur->m_tag == 0) { IGameObject* pRefObj = ((CBaseObject*)((*itCur).m_object))->QueryIGameObject(); if(pRefObj!=0 && !pRefObj->IsSentient() && pRefObj->IsGlobal() && (pRefObj->GetSimTag() == SIM_TAG_START)) { ////////////////////////////////////////////////////////////////////////// // update reference object in the terrain tile according to its current position Vector3 vPos = pRefObj->GetPosition(); CTerrainTile * pTile = pScene->GetRootTile()->GetTileByPoint(vPos.x, vPos.z); if(pTile != NULL) { pRefObj->SetTileContainer(pTile); } ////////////////////////////////////////////////////////////////////////// // basic simulation: path finding, etc. pScene->SetCurrentActor((CBaseObject*)pRefObj); // generate way points pRefObj->PathFinding(dTimeDelta); // move the biped according to way point commands pRefObj->AnimateBiped(dTimeDelta); pRefObj->SetSimTag(SIM_TAG_BASIC); } } } } } } if(CGlobals::WillGenReport()) { CGlobals::GetReport()->SetValue("sentient objects", (int)pScene->GetSentientObjects().size()); } } /// frame move each unexploded missile objects. { for (auto pMissile : pScene->GetMissiles()) { if( !pMissile->IsExploded() ) { pMissile->Animate(dTimeDelta); } } } }
// 2007.8.27: logic changes: the current player is always sentient to all other objects and all other objects are sentient to the current player. void CEnvironmentSim::UpdateGameObjects(double dTimeDelta) { PERF1("EnvSim::UpdateGameObjects"); CSceneObject* pScene = CGlobals::GetScene(); CTerrainTile* duplicateTiles[9]; for (int i = 0;i < (int)pScene->GetSentientObjects().size(); ) { // for each sentient game objects (sentientObj) in the scene IGameObject* sentientObj = pScene->GetSentientObjects()[i]; if (!sentientObj) { pScene->GetSentientObjects().erase(i); OUTPUT_LOG("warn: invalid weak ref found in pScene->GetSentientObjects()\n"); continue; } sentientObj->SetSentientObjCount(0); sentientObj->GetPerceiveList().clear(); Vector3 vPos = sentientObj->GetPosition(); Vector2 vec2Pos(vPos.x, vPos.z); // update itself in the terrain tile according to its current position: CTerrainTile * pTile = pScene->GetRootTile()->GetTileByPoint(vPos.x, vPos.z); if(pTile != NULL) { sentientObj->SetTileContainer(pTile); for(int k=0;k<9;++k) duplicateTiles[k]=NULL; //for each valid terrain tiles(9 or more) in the neighborhood of sentientObj for (int i=0; i<9;++i) { CTerrainTile* pTileAdjacent = pScene->GetRootTile()->GetAdjacentTile(vPos, (CTerrainTileRoot::DIRECTION)i); if(pTileAdjacent!=NULL) { // check if pTile is a new tile that has not been processed by the current sentient object. bool bNewAdjacentTile = true; if((pTileAdjacent==sentientObj->GetTileContainer()) || pTileAdjacent->m_fRadius != sentientObj->GetTileContainer()->m_fRadius) { for(int k=0;k<9 && (duplicateTiles[k]!=NULL);++k) { if(duplicateTiles[k] == pTileAdjacent){ bNewAdjacentTile = false; break; } } } if(bNewAdjacentTile) { { VisitorList_type::iterator itCurCP, itEndCP = pTileAdjacent->m_listVisitors.end(); for( itCurCP = pTileAdjacent->m_listVisitors.begin(); itCurCP != itEndCP;) { IGameObject* AnotherObj = (*itCurCP); if (AnotherObj != nullptr) { if (AnotherObj != sentientObj) { Vector3 vPosAnother = AnotherObj->GetPosition(); Vector2 vec2PosAnother(vPosAnother.x, vPosAnother.z); float fDistSq = (vec2PosAnother - vec2Pos).squaredLength(); if (!AnotherObj->IsSentient()) { //if sentientObj falls inside the sentient area of AnotherObj if ((AnotherObj->IsSentientWith(sentientObj)) && fDistSq <= AnotherObj->GetSentientRadius()*AnotherObj->GetSentientRadius()){ pScene->AddSentientObject(AnotherObj); } } //if AnotherObj falls inside the sentient area of sentientObj if ((sentientObj->IsSentientWith(AnotherObj)) && fDistSq <= sentientObj->GetSentientRadius()*sentientObj->GetSentientRadius()) { sentientObj->SetSentientObjCount(sentientObj->GetSentientObjCount() + 1); // if AnotherObj falls inside the perceptive area of sentientObj if (fDistSq <= sentientObj->GetPerceptiveRadius()*sentientObj->GetPerceptiveRadius()) { sentientObj->GetPerceiveList().push_back(AnotherObj->GetIdentifier()); } } } ++itCurCP; } else itCurCP = pTileAdjacent->m_listVisitors.erase(itCurCP); } } // skip solid object on the root tile, since they are all global objects, not static objects. if(pTileAdjacent!=pScene->GetRootTile()) { // check collision with other static solid objects. for (auto pObject : pTileAdjacent->m_listSolidObj) { IGameObject* AnotherObj = pObject->QueryIGameObject(); if(AnotherObj!=NULL && AnotherObj!=sentientObj && sentientObj->IsSentientWith(AnotherObj) ) { Vector3 vPosAnother = AnotherObj->GetPosition(); Vector2 vec2PosAnother(vPosAnother.x, vPosAnother.z); float fDistSq = (vec2PosAnother-vec2Pos).squaredLength(); //if AnotherObj falls inside the sentient area of sentientObj if(fDistSq<= sentientObj->GetSentientRadius()*sentientObj->GetSentientRadius()) { sentientObj->SetSentientObjCount(sentientObj->GetSentientObjCount()+1); // if AnotherObj falls inside the perceptive area of sentientObj if(fDistSq<= sentientObj->GetPerceptiveRadius()*sentientObj->GetPerceptiveRadius()) { sentientObj->GetPerceiveList().push_back(AnotherObj->GetIdentifier()); } } } } } for(int k=0;k<9;++k) { if(duplicateTiles[k]==NULL) { duplicateTiles[k] = pTileAdjacent; break; } } }//if(bNewAdjacentTile) } } } if(sentientObj->GetSentientObjCount()>0 || sentientObj->IsAlwaysSentient()) { ++i; { // set the simulation tag of all sentient objects and their referenced objects to SIM_TAG_START state. sentientObj->SetSimTag(SIM_TAG_START); if(sentientObj->HasReferences()) { RefList::iterator itCur, itEnd = sentientObj->GetRefList().end(); for (itCur = sentientObj->GetRefList().begin(); itCur!=itEnd; ++itCur) { if(itCur->m_tag == 0) { IGameObject* pRefObj = ((CBaseObject*)((*itCur).m_object))->QueryIGameObject(); if(pRefObj!=0) { pRefObj->SetSimTag(SIM_TAG_START); } } } } } // call on perceived now or in the next pass. } else { sentientObj->On_LeaveSentientArea(); pScene->GetSentientObjects().erase(i); } } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CheckLoS(): This function looks at the player and sees if the player is in range and in line of sight. // // Returns: bool = true if the player is in line of sight // // Mod. Name: Josh Morgan // Mod. Date:8/14/12 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool CSlimeMonsterIdleAI::CheckLoS(void) { //creating the sound sphere Sphere LoSRadius; LoSRadius.SetRadius(LOS_BUBBLE); LoSRadius.SetCenter(m_pParentObject->GetWorldPos()); CSceneObject LoSSphere; LoSSphere.SetCollidableObject(&LoSRadius); // create a return vector to hold all the objects the kd tree returns std::vector <CSceneObject*> ReturnVector; // create a unsigned int that will tell the kd tree what you want put in the return vector // this uses bit wise operations so you can have more then one object returned // use the return flags enum from the kd tree so you know what you can get back int ReturnParams = 0; int ReturnBody = 0; int ReturnObjects = 1<<OBJ_PLAYER | 1<<OBJ_WORLD_COLLISION; CKdTree::GetNearObjects(&LoSSphere, PSFLAG_SPHERE, ReturnParams, ReturnVector, ReturnBody, ReturnObjects); //bool for checking if there's the player, and the position of the player bool bPlayerInRange = false; vec3f tPlayerPos = vec3f(0.0f, 0.0f, 0.0f); for(unsigned int i = 0; i < ReturnVector.size(); i++) { IBaseObject* pObject = ((IBaseObject*)ReturnVector[i]); if(pObject->GetType() == OBJ_PLAYER) { bPlayerInRange = true; tPlayerPos = pObject->GetWorldPos(); break; } } if(!bPlayerInRange) { return false; } //we make a line to the player since he's in aggro range CSceneObject soLineSceneObject; Line LineToPlayer; LineToPlayer.SetVolumeType(VMT_LINE); LineToPlayer.SetStartPoint(vec3f(m_pParentObject->GetWorldPos().x, m_pParentObject->GetWorldPos().y + 100.0f, m_pParentObject->GetWorldPos().z)); LineToPlayer.SetEndPoint(vec3f(tPlayerPos.x, tPlayerPos.y + 100.0f, tPlayerPos.z)); soLineSceneObject.SetCollidableObject(&LineToPlayer); CKdTree::GetNearObjects(&soLineSceneObject, PSFLAG_LINE, ReturnParams, ReturnVector, ReturnBody, ReturnObjects); soLineSceneObject.SetCollidableObject(nullptr); //loop through all the return objects again and check collision with them. for(unsigned int i = 0; i < ReturnVector.size(); ++i) { IBaseObject* pObject = ((IBaseObject*)ReturnVector[i]); if(pObject->GetType() == OBJ_WORLD_COLLISION) { //check to see if our line to the player is obstructed by this ocject vec3f Intersection = vec3f(FLT_MAX, FLT_MAX, FLT_MAX); if(LineToPlayer.LineToAABB(*((AABB*)pObject->GetCollidableObject()), Intersection)) { //D3DXMATRIX mat; //D3DXMatrixIdentity(&mat); //mat._41 = Intersection.x; //mat._42 = Intersection.y; //mat._43 = -500; //DebugShapes::RenderSphere(mat); //we see that there's something between us so I don't have line of sight return false; } } } //set the slime monster to face the player matrix4f _localMat = (*m_pParentObject->GetLocalMat()); matrix4f rotationMatrix; vec2f DtoP = LineToPlayer.GetEndPoint2D() - LineToPlayer.GetStartPoint2D(); if(DtoP.x <= 0.0f) { //spawn facing left rotationMatrix.make_rotation_y( D3DXToRadian(90) ); } else { //spawn to face right rotationMatrix.make_rotation_y( D3DXToRadian(-90) ); } rotationMatrix.axis_pos = _localMat.axis_pos; _localMat = rotationMatrix; m_pParentObject->SetLocalMat(&_localMat); //I SEE HIM! HE'S RIGHT THERE! return true; }
bool __fastcall TUI_ControlObjectAdd::Start(TShiftState Shift) { if (Shift==ssRBOnly){ ExecCommand(COMMAND_SHOWCONTEXTMENU,OBJCLASS_SCENEOBJECT); return false;} TfraObject* fraObject = (TfraObject*)parent_tool->pFrame; VERIFY(fraObject); Fvector p,n; if(!LUI->PickGround(p,UI->m_CurrentRStart,UI->m_CurrentRNorm,1,&n)) return false; { // pick already executed (see top) ESceneObjectTools* ot = dynamic_cast<ESceneObjectTools*>(parent_tool); LPCSTR N; if (ot->IsAppendRandomActive()&&ot->m_AppendRandomObjects.size()){ N = ot->m_AppendRandomObjects[Random.randI(ot->m_AppendRandomObjects.size())].c_str(); }else{ N = ((TfraObject*)parent_tool->pFrame)->Current(); if(!N){ ELog.DlgMsg(mtInformation,"Nothing selected."); return false; } } string256 namebuffer; Scene->GenObjectName(OBJCLASS_SCENEOBJECT, namebuffer, N); CSceneObject *obj = xr_new<CSceneObject>((LPVOID)0,namebuffer); CEditableObject* ref = obj->SetReference(N); if (!ref){ ELog.DlgMsg(mtError,"TUI_ControlObjectAdd:: Can't load reference object."); xr_delete(obj); return false; } /* if (ref->IsDynamic()){ ELog.DlgMsg(mtError,"TUI_ControlObjectAdd:: Can't assign dynamic object."); xr_delete(obj); return false; } */ if (ot->IsAppendRandomActive()){ Fvector S; if (ot->IsAppendRandomRotationActive()){ Fvector p; p.set( Random.randF(ot->m_AppendRandomMinRotation.x,ot->m_AppendRandomMaxRotation.x), Random.randF(ot->m_AppendRandomMinRotation.y,ot->m_AppendRandomMaxRotation.y), Random.randF(ot->m_AppendRandomMinRotation.z,ot->m_AppendRandomMaxRotation.z)); obj->PRotation = p; } if (ot->IsAppendRandomScaleActive()){ Fvector s; if (ot->IsAppendRandomScaleProportional()){ s.x = Random.randF(ot->m_AppendRandomMinScale.x,ot->m_AppendRandomMaxScale.x); s.set (s.x,s.x,s.x); }else{ s.set( Random.randF(ot->m_AppendRandomMinScale.x,ot->m_AppendRandomMaxScale.x), Random.randF(ot->m_AppendRandomMinScale.y,ot->m_AppendRandomMaxScale.y), Random.randF(ot->m_AppendRandomMinScale.z,ot->m_AppendRandomMaxScale.z)); } obj->PScale = s; } } obj->MoveTo(p,n); Scene->SelectObjects(false,OBJCLASS_SCENEOBJECT); Scene->AppendObject( obj ); if (Shift.Contains(ssCtrl)) ExecCommand(COMMAND_SHOW_PROPERTIES); if (!Shift.Contains(ssAlt)) ResetActionToSelect(); } return false; }