/* * Split one sector by a 3D object. */ void CWorld::SplitOneSector(CBrushSector &bscToSplit, CObject3D &obToSplitBy) { // get the brush mip from sector to split CBrushMip *pbmMip = bscToSplit.bsc_pbmBrushMip; // create object to split from sector to split and destroy the sector CBrushSectorSelectionForCSG selbscToSplit; selbscToSplit.Select(bscToSplit); CObject3D obToSplit; pbmMip->ToObject3D(obToSplit, selbscToSplit); pbmMip->DeleteSelectedSectors(selbscToSplit); // copy ambient value from the sector to split to the sector to split with obToSplitBy.ob_aoscSectors.Lock(); obToSplitBy.ob_aoscSectors[0].osc_colAmbient = bscToSplit.bsc_colAmbient; obToSplitBy.ob_aoscSectors[0].osc_colColor = bscToSplit.bsc_colColor; obToSplitBy.ob_aoscSectors[0].osc_ulFlags[0] = bscToSplit.bsc_ulFlags; obToSplitBy.ob_aoscSectors[0].osc_ulFlags[1] = bscToSplit.bsc_ulFlags2; obToSplitBy.ob_aoscSectors[0].osc_ulFlags[2] = bscToSplit.bsc_ulVisFlags; obToSplitBy.ob_aoscSectors.Unlock(); // do 'split sectors' CSG with the objects CObject3D obResult; _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); obResult.CSGSplitSectors(obToSplit, obToSplitBy); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // return the result to the source brush mip try { pbmMip->AddFromObject3D_t(obResult); } catch (char *strError) { FatalError("Unexpected error during split sectors operation: %s", strError); } }
void CSceneGraph::glDraw4Picking(void) { const int pickingstype = (int)m_nPickingType; int i, k; int nsize = m_SceneList.size(); //Apr. 25, 2007 //in volman, the startobjid is modified as 1 const int startobjid = 0; for (i=k=startobjid; i<nsize; i++){ CSceneNode &node = m_SceneList[i]; glPushMatrix(); if (node.m_pFrame) glMultMatrixd(node.m_pFrame->matrix()); CObject3D *pobj = node.m_pObject; CGLDrawParms *pdraw = &node.m_DrawParms; assert(pobj!=NULL); pdraw->BeginDrawing(); switch(pickingstype){ case 0: pobj->DrawPickingObject(k); break; case 1: pobj->DrawPickingObjectFace(k); break; case 2: pobj->DrawPickingObjectLine(k); break; }; k+= pobj->GetPickableElementCount(pickingstype); pdraw->PostDrawing(); glPopMatrix(); } }
CRocket::CRocket(void) { static bool loaded = false; static CObject3D *model = CModelLoader::Get("models/Small_Rocket_B.3ds"); if (!loaded) { ((CMesh*)model->children[0]->children[0])->Reposition(); loaded = true; } CObject3D* mesh = model->Copy(); mesh->SetScale(0.1); mesh->MoveRight(-1.25f); mesh->MoveForward(-0.5 + 1); mesh->MoveUp(-0.25-0.2f); this->Add(mesh); boundingShape = EBoundingShape::Sphere; followTarget = false; light = new CPointLight(Vector3(), YELLOW); //light->range = 3.0f; this->Add(light); }
int CCia3dObj::GetTotalTriangleCount(void) { int i, ntri=0; int nobj = UnsplitObjectCount(); for (i=0; i<nobj; i++){ CObject3D * p = m_pObjList[i]; const char *des = p->Description(); if (strcmp(des, "tri") == 0){ //a triangle mesh; CTriangleObj *ptri = (CTriangleObj*)p; int nn = ptri->m_nPolygonCount; ntri+=nn; } } return ntri; }
void CSceneGraph::_exportPovrayMesh(FILE *fp) { int i; const int nsize = m_SceneList.size(); //draw all the objects; for (i=0; i<nsize; i++){ CSceneNode &node = m_SceneList[i]; CObject3D *pobj = node.m_pObject; assert(pobj!=NULL); const double *matrix = node.m_pFrame->matrix(); fprintf(fp, "#declare %s =\n", pobj->GetObjectName()); pobj->exportFile(fp, ".pov", matrix); fprintf(fp, "\n\n\n"); } }
int CCia3dObj::ObjectCount(int objidbuff[], const int bufflen) { int i, j; CDynamicArray<int> A; for (i=0; i<CIA3D_SUBOBJ_LIMIT; i++){ CObject3D *p = m_pObjList[i]; if (p==NULL) continue; int bsize= p->ObjectCount(objidbuff, bufflen); for (j=0; j<bsize; j++) A.AddWithNoDuplication(objidbuff[j]); } int asize = A.GetSize(); assert(asize>0 && asize<bufflen); for (i=0; i<asize; i++) objidbuff[i] = A[i]; return asize; }
static void _getObjectAndLineID(const int picktype, const int pickedid, CSceneGraph &scene, int& objid, int& vid1, int &vid2) { int i, c1, c2; for (i=0, c1=0; i<scene.size(); i++){ CSceneNode *p = scene.GetSceneNode(i); CObject3D *pobj = p->m_pObject; if (!pobj) continue; c2 = c1+ pobj->GetPickableElementCount(picktype); if (pickedid>=c1 && objid<c2){ //obj found; pobj->GetPickedLine(pickedid-c1, vid1, vid2); objid = i; if (picktype==CSceneGraph::PICK_LINE) DUMP_LINE_INFO((CPolyObj*)pobj, vid1, vid2); break; } c1=c2; } }
static void ExportPovrayObjects(CSceneGraph & sg, FILE *fp) { int i; const int nsize = sg.size(); if (nsize==0) return; //draw all the objects; fprintf(fp, "union{\n"); for (i=0; i<nsize; i++){ CSceneNode *node = sg.GetSceneNode(i); CObject3D *pobj = node->m_pObject; assert(pobj!=NULL); fprintf(fp, "object {\n"); fprintf(fp, "\t%s\n", pobj->GetObjectName()); fprintf(fp, "\ttexture { CIA3DTex%d }\n", i); //fprintf(fp, "\ttexture { White_Chocolate }\n"); fprintf(fp, "}\n"); } fprintf(fp, "}\n\n\n"); }
static void _getObjectAndFaceID(const CSceneGraph::PICKING_TYPE_ID picktype, const int pickedid, CSceneGraph &scene, int& objid, int& faceid) { int c1=0, c2=0; objid=-1, faceid=-1; for (int i=0; i<scene.size(); i++){ CSceneNode *p = scene.GetSceneNode(i); CObject3D *pobj = p->m_pObject; if (!pobj) continue; c2 = c1+ pobj->GetPickableElementCount(picktype); if (pickedid>=c1 && pickedid<c2){ // find obj; objid = i; faceid = pickedid - c1; if (picktype==CSceneGraph::PICK_FACE) DUMP_POLY_INFO((CPolyObj*)pobj, faceid); break; } c1=c2; } }
static void _glDrawNodeBoundingBox(CSceneNode *pnode, const Vector3f &linecolor) { if (pnode==NULL) return; glPushMatrix(); if (pnode->m_pFrame) glMultMatrixd(pnode->m_pFrame->matrix()); CGLDrawParms *pdraw = &pnode->m_DrawParms; pdraw->BeginDrawing(); CObject3D *p = pnode->m_pObject; if (p == NULL) p= pnode->m_pSimulationObject; AxisAlignedBox box; p->GetBoundingBox(box); glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_2D); glLineWidth(2); glColor3f(linecolor.x, linecolor.y, linecolor.z); glDisable(GL_LIGHTING); const Vector3d& p0=box.minp; const Vector3d& p1=box.maxp; DrawBoundingBox(p0, p1); const Vector3d dist = (p1 - p0)*0.33; glLineWidth(4); glColor3f(1.0,0,0); glBegin(GL_LINES); glVertex3f(p0.x, p0.y, p0.z); glVertex3f(p0.x+dist.x, p0.y, p0.z); glEnd(); glColor3f(0,1,0); glBegin(GL_LINES); glVertex3f(p0.x, p0.y, p0.z); glVertex3f(p0.x, dist.y+p0.y, p0.z); glEnd(); glColor3f(0,0,1); glBegin(GL_LINES); glVertex3f(p0.x, p0.y, p0.z); glVertex3f(p0.x, p0.y, p0.z+dist.z); glEnd(); pdraw->PostDrawing(); glPopMatrix(); }
/* * Copy selected sectors of a source brush to a 3D object. */ void CWorld::CopySourceBrushSectorsToObject( CEntity &enBrush, CBrushSectorSelectionForCSG &bscselSectors, const CPlacement3D &plSourcePlacement, CObject3D &obObject, const CPlacement3D &plTargetPlacement, DOUBLEaabbox3D &boxSourceAbsolute ) { ASSERT(GetFPUPrecision()==FPT_53BIT); // get the brush mip from the entity CBrushMip &bmBrushMip = *GetBrushMip(enBrush); // calculate placement of the brush in absolute space (taking relative // world placement and entity placement in account) CPlacement3D plBrush = enBrush.en_plPlacement; plBrush.RelativeToAbsolute(plSourcePlacement); // copy selected sectors of brush to object3d object bmBrushMip.ToObject3D(obObject, bscselSectors); // make a copy of the object and find its box in absolute space CObject3D obAbsolute; obAbsolute = obObject; CSimpleProjection3D_DOUBLE prToAbsolute; prToAbsolute.ObjectPlacementL() = plBrush; prToAbsolute.ViewerPlacementL() = CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0)); prToAbsolute.Prepare(); obAbsolute.Project(prToAbsolute); obAbsolute.GetBoundingBox(boxSourceAbsolute); // project the brush into target space CSimpleProjection3D_DOUBLE prSimple; prSimple.ObjectPlacementL() = plBrush; prSimple.ViewerPlacementL() = plTargetPlacement; prSimple.Prepare(); obObject.Project(prSimple); }
void CPhysics::TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex) { CObject3D *object = (CObject3D*)NewtonBodyGetUserData(body); float m[16]; NewtonBodyGetMatrix(body, m); Matrix4 M = Matrix4(m); Vector3 destination = M.GetPosition(); Vector3 velocity = (destination - object->GetWorldPosition()) * object->physicsDelay; object->velocity = velocity; Vector3 pos = object->position; object->SetMatrix( Matrix4(m) ); object->SetPosition(pos); // setting entire matrix each physics frame might cause desync with the renderer, // that might run more often, resulting in drawing the object in the same location // twice in a row // Instead each physics frame we set the object's velocity so that it reaches // the desginated position in 1/10th of a second }
void CScene3D::Render() { if(m_Camera) { CMatrix4 viewproj = m_Camera->GetProjection(); viewproj *= m_Camera->GetView(); m_Render->SetTransform(ETT_VIEWPROJ, viewproj); } else return; const CViewFrustum& frustum = m_Camera->GetFrustum(); m_RenderList.Clear(); m_Octree.GetVisibleList(frustum, m_RenderList); CList<CObject3D*>::CIterator its = m_RenderList.Begin(); while(its != m_RenderList.End()) { CObject3D* drw = *its; drw->Render(); #ifdef _DEBUG drw->DebugRender(); #endif ++its; } #ifdef _DEBUG m_Octree.DebugRender(frustum); m_Render->SetTransform(ETT_MODEL, CMatrix4::IDENTY); CDebugRenderer::Instance()->Render(); #endif }
////////////////////////////////////////////////////////////////////////// // Check if given object is in frustum ////////////////////////////////////////////////////////////////////////// bool CFrustum::CheckMesh( CObject3D &mesh ) { Vector3 pos = mesh.GetWorldPosition(); if (mesh.boundingShape == EBoundingShape::Box) { Vector3 size = mesh.geometry->boundingBox.GetSize(); size.x *= mesh.scale.x; size.y *= mesh.scale.y; size.z *= mesh.scale.z; Vector3 pos = mesh.GetWorldPosition(); pos.x += (mesh.geometry->boundingBox.min.x + size.x/2) * mesh.scale.x; pos.y += (mesh.geometry->boundingBox.min.y + size.y/2) * mesh.scale.y; pos.z += (mesh.geometry->boundingBox.min.z + size.z/2) * mesh.scale.z; return CheckBox(pos.x, pos.y, pos.z, size.x, size.y, size.z); } else { float maxScale = max(max(mesh.scale.x, mesh.scale.y), mesh.scale.z); float boundingRadius = maxScale * mesh.geometry->boundingSphere; return CheckSphere(pos.x, pos.y, pos.z, boundingRadius); } }
int CCia3dObj::ObjectSplit(CCia3dObj * buff[], const int bufflen) { const int idsize = 2048; int objidbuff[idsize], objidbuff2[idsize]; CObject3D * pobjs[idsize]; const int n1 = ObjectCount(objidbuff, idsize); if (n1==1){ printf("There is only one object, no need to split!\n"); assert(0); } for (int i=0; i<n1; i++){ buff[i] = new CCia3dObj; assert(buff[i]!=NULL); } for (int i=0; i<CIA3D_SUBOBJ_LIMIT; i++){ CObject3D *p = m_pObjList[i]; if (p==NULL) break; const int n2 = p->ObjectCount(objidbuff2, idsize); if (n2==1){ int key = objidbuff2[0]; int index = SEARCH_KEY_POS(objidbuff, n1, key); buff[index]->addObject(p); p->SetCustomizedObjectName(index); } else{ const int n3 = p->SplitIntoSubObj(objidbuff2, n2, pobjs); assert(n3==n2); for (int j=0; j<n2; j++){ CObject3D * pobj = pobjs[j]; int key = objidbuff2[j]; int index = SEARCH_KEY_POS(objidbuff, n1, key); buff[index]->addObject(pobj); pobj->SetCustomizedObjectName(index); } delete p; } m_pObjList[i] = NULL; } return 1; }
/* * Do some CSG operation with one brush in this world and one brush in other world. */ void CWorld::DoCSGOperation( CEntity &enThis, CWorld &woOther, CEntity &enOther, const CPlacement3D &plOther, void (CObject3D::*DoCSGOpenSector)(CObject3D &obA, CObject3D &obB), void (CObject3D::*DoCSGClosedSectors)(CObject3D &obA, CObject3D &obB) ) { // assure that floating point precision is 53 bits AssureFPT_53(); // get relevant brush mips in each brush CBrushMip &bmThis = *GetBrushMip(enThis); CBrushMip &bmOther = *GetBrushMip(enOther); if (&bmThis==NULL || &bmOther==NULL) { return; } // get open sector of the other brush to object CBrushSectorSelectionForCSG selbscOtherOpen; bmOther.SelectOpenSector(selbscOtherOpen); CObject3D obOtherOpen; DOUBLEaabbox3D boxOtherOpen; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherOpen, plOther, obOtherOpen, enThis.en_plPlacement, boxOtherOpen); // if there is an open sector in other object if (obOtherOpen.ob_aoscSectors.Count()>0) { CObject3D obResult; // deportalize the open sector obOtherOpen.TurnPortalsToWalls(); // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherOpen, obThis); // do the open sector CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGOpenSector)(obThis, obOtherOpen); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the open sector directly in the result obResult = obOtherOpen; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } // get closed sectors of the other brush to object CBrushSectorSelectionForCSG selbscOtherClosed; bmOther.SelectClosedSectors(selbscOtherClosed); CObject3D obOtherClosed; DOUBLEaabbox3D boxOtherClosed; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherClosed, plOther, obOtherClosed, enThis.en_plPlacement, boxOtherClosed); // if there are closed sectors in other object if (obOtherClosed.ob_aoscSectors.Count()>0) { CObject3D obResult; // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherClosed, obThis); // do the closed sectors CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGClosedSectors)(obThis, obOtherClosed); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the closed sectors directly in the result obResult = obOtherClosed; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } }
void CEffectsGame::CreateScene() { pScene->CreateSkybox("clear"); NewtonBody *bFloor = AddBox(pScene, pWorld, Vector3(0,-0.5,0), Vector3(1000,1,1000), Vector3()); NewtonCollision *col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); Vector3 v[4] = { Vector3(-1000,0.5f,-1000), Vector3(-1000,0.5f,+1000), Vector3(+1000,0.5f,+1000), Vector3(+1000,0.5f,-1000) }; NewtonTreeCollisionAddFace(col, 4, &v[0][0], sizeof(Vector3), 1); NewtonTreeCollisionEndBuild(col, 0); NewtonBodySetCollision(bFloor, col); CObject3D *f = (CObject3D*)NewtonBodyGetUserData(bFloor); f->visible = false; NewtonBodySetMaterialGroupID(bFloor, gLevelChunksMaterialID); // floor static CTexture *floorTex = new CTexture("textures/512.png"); CMaterial *floorMat = new CMaterial(); floorMat->features = EShaderFeature::LIGHT | EShaderFeature::FOG | EShaderFeature::SHADOW | EShaderFeature::TEXTURE; CPlaneGeometry *floorGeom = new CPlaneGeometry(1000,1000); CObject3D *floor = new CMesh( floorGeom, floorMat ); floor->geometry->materials.AddToTail(floorMat); floorMat->pTexture = floorTex; floorGeom->SetTextureScale(40,40); floor->SetPosition(-500, 0, -500); pScene->Add(floor); pLevel = new CLevel(pScene, pWorld); pLevel->Create(32,80,32); int width = 24; int depth = 24; int storeys = 8; int storyHeight = 8; for (int y=0; y<storeys*storyHeight; y++) for (int x=0; x<width; x++) for (int z=0; z<depth; z++) { int block = 0; if (x==0 || z==0 || x==width-1 || z==depth-1) block = 1; if (y%storyHeight == storyHeight-1) block = 1; if (x>5 && z>5 && x<width-5 && z<depth-5) block = 0; if (y%storyHeight > 2 && y%storyHeight <= 4) { if (x%8 >= 2 && x%8 < 7) block = 0; if (z%8 >= 2 && z%8 < 7) block = 0; } if ((x==5 && z==5) || (x==width-5 && z==depth-5) || (x==5 && z==depth-5) || (x==width-5 && z==5) ) block = 4; if (block > 0) block = 4; pLevel->GetTile(x,y,z)->type = block; } int sx = 55; int sz = 55; pLevel->Recreate(); for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { pLevel->GetChunk(x,y,z)->RecreateCollision(); } // once the map has been created, creatie bodies that will collide /*for (int x=0; x<pLevel->sizeX; x++) for (int y=0; y<pLevel->sizeY; y++) for (int z=0; z<pLevel->sizeZ; z++) { if (pLevel->GetTile(x,y,z)->type == 0) continue; CObject3D *o = new CObject3D(); o->SetPosition(Vector3(x+0.5, y+0.5, z+0.5)); NewtonBody *box = CPhysics::CreateBox(pWorld, o, 1,1,1, 0); NewtonBodySetFreezeState(box, 1); delete o; }*/ // let's create a collision tree for each chunk /* for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { NewtonCollision * col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); CArray<Vector3> &verts = pLevel->GetChunk(x,y,z)->pMesh->geometry->vertices; for (int i=0; i<pLevel->GetChunk(x,y,z)->pMesh->geometry->faces.Size(); i++) { Face3 face = pLevel->GetChunk(x,y,z)->pMesh->geometry->faces[i]; Vector3 v[] = { verts[face.a], verts[face.b], verts[face.c] }; NewtonTreeCollisionAddFace(col, 3, &v[0][0], sizeof(Vector3), 1); } NewtonTreeCollisionEndBuild(col, 1); // create body float m[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; NewtonBody *body = NewtonCreateBody(pWorld, col, &m[0]); NewtonReleaseCollision(pWorld, col); NewtonBody } */ /* CreateBuilding(0,0,0, 3,8,3); CreateBuilding(20,0,-10, 2,4,6); CreateBuilding(-5,0,-20, 5,2,3); */ // point light that will circle the building pLight = new CPointLight(Vector3(), SRGBA(255,200,50)); pLight->range = 8.0f; pLight->overbright = true; pScene->Add(pLight); pScene->fog = new SFog( SRGBA(172,201,241, 255), 200, 500); // point light at 0,1,0 CLight *pLight = new CPointLight(Vector3(0,1,0), RED);//SRGBA(255,233,155,255)); //pScene->Add( pLight ); pLight->specular = pLight->color;//SRGBA(255,255,255,100); pLight->range = 1; pLight->intensity = 1; // directional Sun light CDirectionalLight *pDirLight = new CDirectionalLight(Vector3(0,0,0), SRGBA(255,225,175,255)); pDirLight->SetPosition(+70,90,-70); pDirLight->LookAt(Vector3()); pDirLight->UpdateMatrixWorld(true); pDirLight->shadowNear = 20; pDirLight->shadowFar = 200; pDirLight->castShadow = true; float aspect = (float)gEngine.width / gEngine.height; pDirLight->width = 200.0f; pDirLight->height = pDirLight->width / aspect; pScene->Add( pDirLight ); // ambient light pScene->ambientColor = SRGBA(200,200,255,255); pCamera->LookAt(Vector3()); }
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(); }