// util //--------------------------------------------------------------------------------------------------------------- ManualObject* App::Create2D(const String& mat, Real s, bool dyn) { ManualObject* m = mSceneMgr->createManualObject(); m->setDynamic(dyn); m->setUseIdentityProjection(true); m->setUseIdentityView(true); m->setCastShadows(false); m->estimateVertexCount(4); m->begin(mat, RenderOperation::OT_TRIANGLE_STRIP); m->position(-s,-s*asp, 0); m->textureCoord(0, 1); m->position( s,-s*asp, 0); m->textureCoord(1, 1); m->position(-s, s*asp, 0); m->textureCoord(0, 0); m->position( s, s*asp, 0); m->textureCoord(1, 0); m->end(); //TODO:replace OT_TRIANGLE_FAN with a more friendly version for D3D11 as it is not supported /* m->estimateVertexCount(6); m->begin(mat, RenderOperation::OT_TRIANGLE_LIST); m->position(-s,-s*asp, 0); m->textureCoord(0, 1); m->position( s,-s*asp, 0); m->textureCoord(1, 1); m->position( s, s*asp, 0); m->textureCoord(1, 0); m->position(-s, s*asp, 0); m->textureCoord(0, 0); m->position(-s,-s*asp, 0); m->textureCoord(0, 1); m->position( s, s*asp, 0); m->textureCoord(1, 0); m->end(); */ AxisAlignedBox aabInf; aabInf.setInfinite(); m->setBoundingBox(aabInf); // always visible m->setRenderQueueGroup(RQG_Hud2); return m; }
void App::CreateRacingLine() { //void ROADPATCH::AddRacinglineScenenode(SCENENODE * node, ROADPATCH * nextpatch, ManualObject* m = mSceneMgr->createManualObject(); m->begin("track/Racingline", RenderOperation::OT_TRIANGLE_LIST); int ii = 0; const std::list <ROADSTRIP>& roads = pGame->track.GetRoadList(); for (std::list <ROADSTRIP>::const_iterator it = roads.begin(); it != roads.end(); ++it) { const std::list <ROADPATCH>& pats = (*it).GetPatchList(); for (std::list <ROADPATCH>::const_iterator i = pats.begin(); i != pats.end(); ++i) { const VERTEXARRAY* a = &((*i).racingline_vertexarray); if (!a) continue; int verts = a->vertices.size(); if (verts == 0) continue; int faces = a->faces.size(); for (int v = 0; v < verts; v += 3) m->position(a->vertices[v+0], a->vertices[v+2], -a->vertices[v+1]); for (int f = 0; f < faces; ++f) m->index(ii + a->faces[f]); ii += verts/3; } } m->setCastShadows(false); m->end(); hud->ndLine = mSceneMgr->getRootSceneNode()->createChildSceneNode(); hud->ndLine->attachObject(m); //ndLine->setVisible(pSet->racingline); }
// CreatePart mesh //--------------------------------------------------- void CarModel::CreatePart(SceneNode* ndCar, Vector3 vPofs, String sCar2, String sCarI, String sMesh, String sEnt, bool ghost, uint32 visFlags, AxisAlignedBox* bbox, String stMtr, VERTEXARRAY* var, bool bLogInfo) { if (FileExists(sCar2 + sMesh)) { Entity* ent = mSceneMgr->createEntity(sCarI + sEnt, sDirname + sMesh, sCarI); if (bbox) *bbox = ent->getBoundingBox(); if (ghost) { ent->setRenderQueueGroup(RQG_CarGhost); ent->setCastShadows(false); } else if (visFlags == RV_CarGlass) ent->setRenderQueueGroup(RQG_CarGlass); ndCar->attachObject(ent); ent->setVisibilityFlags(visFlags); if (bLogInfo) LogMeshInfo(ent, sDirname + sMesh); } else { ManualObject* mo = pApp->CreateModel(mSceneMgr, stMtr, var, vPofs, false, false, sCarI+sEnt); if (!mo) return; if (bbox) *bbox = mo->getBoundingBox(); if (ghost) { mo->setRenderQueueGroup(RQG_CarGhost); mo->setCastShadows(false); } else if (visFlags == RV_CarGlass) mo->setRenderQueueGroup(RQG_CarGlass); ndCar->attachObject(mo); mo->setVisibilityFlags(visFlags); /** /// save .mesh MeshPtr mpCar = mInter->convertToMesh("Mesh" + sEnt); MeshSerializer* msr = new MeshSerializer(); msr->exportMesh(mpCar.getPointer(), sDirname + sMesh);/**/ } }
// Sky Dome //------------------------------------------------------------------------------------- void CScene::CreateSkyDome(String sMater, Vector3 sc, float yaw) { ManualObject* m = app->mSceneMgr->createManualObject(); m->begin(sMater, RenderOperation::OT_TRIANGLE_LIST); // divisions- quality int ia = 32*2, ib = 24,iB = 24 +1/*below_*/, i=0; //int ia = 4, ib = 4, i=0; // angles, max float a,b; const float B = PI_d/2.f, A = 2.f*PI_d; float bb = B/ib, aa = A/ia; // add ia += 1; // up/dn y ) for (b = 0.f; b <= B+bb/*1*/*iB; b += bb) { float cb = sinf(b), sb = cosf(b); float y = sb; // circle xz o for (a = 0.f; a <= A; a += aa, ++i) { float x = cosf(a)*cb, z = sinf(a)*cb; m->position(x,y,z); m->textureCoord(a/A, b/B); if (a > 0.f && b > 0.f) // rect 2tri { m->index(i-1); m->index(i); m->index(i-ia); m->index(i-1); m->index(i-ia); m->index(i-ia-1); } } } m->end(); AxisAlignedBox aab; aab.setInfinite(); m->setBoundingBox(aab); // always visible m->setRenderQueueGroup(RQG_Sky); m->setCastShadows(false); #ifdef SR_EDITOR m->setVisibilityFlags(RV_Sky); // hide on minimap #endif app->ndSky = app->mSceneMgr->getRootSceneNode()->createChildSceneNode(); app->ndSky->attachObject(m); app->ndSky->setScale(sc); Quaternion q; q.FromAngleAxis(Degree(-yaw), Vector3::UNIT_Y); app->ndSky->setOrientation(q); }
ManualObject* CHud::Create2D(const String& mat, SceneManager* sceneMgr, Real s, // scale pos bool dyn, bool clr, Real mul, Vector2 ofs, uint32 vis, uint8 rndQue, int cnt) { ManualObject* m = sceneMgr->createManualObject(); m->setDynamic(dyn); m->setUseIdentityProjection(true); m->setUseIdentityView(true); m->setCastShadows(false); m->estimateVertexCount(cnt * 4); m->begin(mat, cnt > 1 ? RenderOperation::OT_TRIANGLE_LIST : RenderOperation::OT_TRIANGLE_STRIP); const static Vector2 uv[4] = { Vector2(0.f,1.f),Vector2(1.f,1.f),Vector2(0.f,0.f),Vector2(1.f,0.f) }; for (int i=0; i < cnt; ++i) { m->position(-s,-s*asp, 0); m->textureCoord(uv[0]*mul + ofs); if (clr) m->colour(0,1,0); m->position( s,-s*asp, 0); m->textureCoord(uv[1]*mul + ofs); if (clr) m->colour(0,0,0); m->position(-s, s*asp, 0); m->textureCoord(uv[2]*mul + ofs); if (clr) m->colour(1,1,0); m->position( s, s*asp, 0); m->textureCoord(uv[3]*mul + ofs); if (clr) m->colour(1,0,0); } if (cnt > 1) for (int i=0; i < cnt; ++i) { int n = i*4; m->quad(n,n+1,n+3,n+2); } m->end(); AxisAlignedBox aabInf; aabInf.setInfinite(); m->setBoundingBox(aabInf); // always visible m->setVisibilityFlags(vis); m->setRenderQueueGroup(rndQue); //RQG_Hud2 return m; }
void App::CreateVdrTrack(std::string strack, TRACK* pTrack) { // materials ------------- std::vector<OGRE_MESH>& meshes = pTrack->ogre_meshes; std::string sMatCache = strack + ".matdef", sMatOrig = "_" + sMatCache, sPathCache = PATHMANAGER::ShaderDir() + "/" + sMatCache, sPathOrig = gcom->TrkDir() +"objects/"+ sMatOrig; bool hasMatOrig = boost::filesystem::exists(sPathOrig), hasMatCache = boost::filesystem::exists(sPathCache); bool bGenerate = 0, gen = !hasMatOrig && !hasMatCache || bGenerate; // set 1 to force generate for new vdrift tracks //TODO .mat ..rewrite this code for new system #if 0 if (gen) { String sMtrs; for (int i=0; i < meshes.size(); i++) { OGRE_MESH& msh = meshes[i]; if (msh.sky /*&& ownSky*/) continue; if (!msh.newMtr) continue; // create material if new bool found = true; TexturePtr tex = TextureManager::getSingleton().getByName(msh.material); if (tex.isNull()) try{ tex = TextureManager::getSingleton().load(msh.material, rgDef); } catch(...){ found = false; } msh.found = found; // dont create meshes for not found textures, test if (!found) continue; #if 0 // use 0 for some tracks (eg.zandvoort) - have alpha textures for all! if (!tex.isNull() && tex->hasAlpha()) msh.alpha = true; // for textures that have alpha #endif if (msh.alpha) sMtrs += "["+msh.material+"]\n"+ " parent = 0vdrAlpha\n"+ " diffuseMap_512 = "+msh.material+"\n"; else sMtrs += "["+msh.material+"]\n"+ " parent = 0vdrTrk\n"+ " diffuseMap_512 = "+msh.material+"\n"; } std::ofstream fileout(sPathCache.c_str()); if (!fileout) LogO("Error: Can't save vdrift track matdef!"); fileout.write(sMtrs.c_str(), sMtrs.size()); fileout.close(); hasMatCache = true; } #endif // meshes ------------- std::vector<Entity*> ents; static int ii = 0; int i; for (i=0; i < meshes.size(); ++i) { OGRE_MESH& msh = meshes[i]; if (msh.sky /*&& ownSky*/) continue; if (!msh.found) continue; //if (strstr(msh.material.c_str(), "tree")!=0) continue; //LogO( String("--- model: ") + msh.name + " mtr:" + msh.material + //" v:" + toStr(msh.mesh->vertices.size()) + " f:" + toStr(msh.mesh->faces.size()) ); //if (ownSky && msh.sky) if (!msh.sky) { ManualObject* m = CreateModel(mSceneMgr, msh.material, msh.mesh, Vector3(0,0,0), false, true); //if (!m) continue; if (msh.sky) m->setCastShadows(false); MeshPtr mp = m->convertToMesh("m"+toStr(ii+i)); Entity* e = mSceneMgr->createEntity(mp); ents.push_back(e); } } ii += i; // static geom ------------- scn->vdrTrack = mSceneMgr->createStaticGeometry("track"); scn->vdrTrack->setRegionDimensions(Vector3::UNIT_SCALE * 1000); // 1000 scn->vdrTrack->setOrigin(Vector3::ZERO); scn->vdrTrack->setCastShadows(true); for (std::vector<Entity*>::iterator it = ents.begin(); it != ents.end(); ++it) scn->vdrTrack->addEntity(*it, Vector3::ZERO); scn->vdrTrack->build(); //mStaticGeom->dump("_track-sg.txt"); }
ManualObject* CHud::CreateVdrMinimap() { asp = float(app->mWindow->getWidth())/float(app->mWindow->getHeight()); // get track sizes minX=FLT_MAX; maxX=FLT_MIN; minY=FLT_MAX; maxY=FLT_MIN; const std::list <ROADSTRIP>& roads = app->pGame->track.GetRoadList(); for (std::list <ROADSTRIP>::const_iterator it = roads.begin(); it != roads.end(); ++it) { const std::list <ROADPATCH>& pats = (*it).GetPatchList(); for (std::list <ROADPATCH>::const_iterator i = pats.begin(); i != pats.end(); ++i) { for (int iy=0; iy<4; ++iy) for (int ix=0; ix<4; ++ix) { const MATHVECTOR<float,3>& vec = (*i).GetPatch().GetPoint(ix,iy); Real x = vec[0], y = vec[2]; if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; } } } float fMapSizeX = maxX - minX, fMapSizeY = maxY - minY; // map size float size = std::max(fMapSizeX, fMapSizeY); scX = 1.f / size; scY = 1.f / size; ManualObject* m = app->mSceneMgr->createManualObject(); m->begin("hud/Minimap", RenderOperation::OT_TRIANGLE_LIST); int ii = 0; for (std::list <ROADSTRIP>::const_iterator it = roads.begin(); it != roads.end(); ++it) { const std::list <ROADPATCH>& pats = (*it).GetPatchList(); for (std::list <ROADPATCH>::const_iterator i = pats.begin(); i != pats.end(); ++i) { float p[16][3]; int a=0; for (int y=0; y<4; ++y) for (int x=0; x<4; ++x) { const MATHVECTOR<float,3>& vec = (*i).GetPatch().GetPoint(x,y); p[a][0] = vec[0]; p[a][1] = vec[2]; p[a][2] = vec[1]; a++; } a = 0; // normal Vector3 pos (p[a ][2], -p[a ][0], p[a ][1]); Vector3 posX(p[a+3][2], -p[a+3][0], p[a+3][1]); posX-=pos; posX.normalise(); Vector3 posY(p[a+12][2],-p[a+12][0],p[a+12][1]); posY-=pos; posY.normalise(); Vector3 norm = posX.crossProduct(posY); norm.normalise();/**/ for (int y=0; y<4; ++y) for (int x=0; x<4; ++x) { Vector3 pos( (p[a][0] - minX)*scX*2-1, // pos x,y = -1..1 -(p[a][1] - minY)*scY*2+1, 0); a++; m->position(pos); m->normal(norm);/**/ Real c = std::min(1.f, std::max(0.3f, 1.f - 2.4f * powf( fabs(norm.y) /*norm.absDotProduct(vLi)*/, 0.7f) )); m->colour(ColourValue(c,c,c,1)); m->textureCoord(x/3.f,y/3.f); if (x<3 && y<3) { int a = ii+x+y*4; m->index(a+0); m->index(a+1); m->index(a+4); m->index(a+1); m->index(a+4); m->index(a+5); } } ii += 16; } } m->end(); m->setUseIdentityProjection(true); m->setUseIdentityView(true); // on hud m->setCastShadows(false); AxisAlignedBox aab; aab.setInfinite(); m->setBoundingBox(aab); // draw always m->setRenderingDistance(100000.f); m->setRenderQueueGroup(RQG_Hud2); m->setVisibilityFlags(RV_Hud); return m; }
//------------------------------------------------------------------------------------------------------- // Create //------------------------------------------------------------------------------------------------------- void CarModel::Create() { //if (!pCar) return; String strI = toStr(iIndex)+ (eType == CT_TRACK ? "Z" : (eType == CT_GHOST2 ? "V" :"")); mtrId = strI; String sCarI = "Car" + strI; resGrpId = sCarI; String sCars = PATHMANAGER::Cars() + "/" + sDirname; resCar = sCars + "/textures"; String rCar = resCar + "/" + sDirname; String sCar = sCars + "/" + sDirname; bool ghost = false; //isGhost(); //1 || for ghost test bool bLogInfo = !isGhost(); // log mesh info bool ghostTrk = isGhostTrk(); // Resource locations ----------------------------------------- /// Add a resource group for this car ResourceGroupManager::getSingleton().createResourceGroup(resGrpId); Ogre::Root::getSingletonPtr()->addResourceLocation(sCars, "FileSystem", resGrpId); Ogre::Root::getSingletonPtr()->addResourceLocation(sCars + "/textures", "FileSystem", resGrpId); pMainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); SceneNode* ndCar = pMainNode->createChildSceneNode(); // -------- Follow Camera -------- if (mCamera && pCar) { fCam = new FollowCamera(mCamera, pSet); fCam->chassis = pCar->dynamics.chassis; fCam->loadCameras(); // set in-car camera position to driver position for (std::vector<CameraAngle*>::iterator it=fCam->mCameraAngles.begin(); it!=fCam->mCameraAngles.end(); ++it) { if ((*it)->mName == "Car driver") (*it)->mOffset = Vector3(driver_view[0], driver_view[2], -driver_view[1]); else if ((*it)->mName == "Car bonnet") (*it)->mOffset = Vector3(hood_view[0], hood_view[2], -hood_view[1]); } } CreateReflection(); // next checkpoint marker bool deny = pApp->gui->pChall && !pApp->gui->pChall->chk_beam; if (eType == CT_LOCAL && !deny) { entNextChk = mSceneMgr->createEntity("Chk"+strI, "check.mesh"); entNextChk->setRenderQueueGroup(RQG_Weather); entNextChk->setCastShadows(false); ndNextChk = mSceneMgr->getRootSceneNode()->createChildSceneNode(); ndNextChk->attachObject(entNextChk); entNextChk->setVisibilityFlags(RV_Hud); ndNextChk->setVisible(false); } ///() grass sphere test #if 0 Entity* es = mSceneMgr->createEntity(sCarI+"s", "sphere.mesh", sCarI); es->setRenderQueueGroup(RQG_CarGhost); MaterialPtr mtr = MaterialManager::getSingleton().getByName("pipeGlass"); es->setMaterial(mtr); ndSph = mSceneMgr->getRootSceneNode()->createChildSceneNode(); ndSph->attachObject(es); #endif /// Create Models: body, interior, glass //------------------------------------------------- Vector3 vPofs(0,0,0); AxisAlignedBox bodyBox; uint8 g = RQG_CarGhost; all_subs=0; all_tris=0; //stats if (bRotFix) ndCar->setOrientation(Quaternion(Degree(90),Vector3::UNIT_Y)*Quaternion(Degree(180),Vector3::UNIT_X)); CreatePart(ndCar, vPofs, sCar, sCarI, "_body.mesh", "", ghost, RV_Car, &bodyBox, sMtr[Mtr_CarBody], pCar ? &pCar->bodymodel.mesh : 0, bLogInfo); vPofs = Vector3(interiorOffset[0],interiorOffset[1],interiorOffset[2]); //x+ back y+ down z+ right if (!ghost) CreatePart(ndCar, vPofs, sCar, sCarI, "_interior.mesh", "i", ghost, RV_Car, 0, sMtr[Mtr_CarBody]+"i", pCar ? &pCar->interiormodel.mesh : 0, bLogInfo); vPofs = Vector3::ZERO; CreatePart(ndCar, vPofs, sCar, sCarI, "_glass.mesh", "g", ghost, RV_CarGlass, 0, sMtr[Mtr_CarBody]+"g", pCar ? &pCar->glassmodel.mesh : 0, bLogInfo); // wheels ---------------------- for (int w=0; w < 4; ++w) { String siw = "Wheel" + strI + "_" + toStr(w); ndWh[w] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); String sMesh = "_wheel.mesh"; // custom if (w < 2 && FileExists(sCar + "_wheel_front.mesh")) sMesh = "_wheel_front.mesh"; else // 2| if (w >= 2 && FileExists(sCar + "_wheel_rear.mesh") ) sMesh = "_wheel_rear.mesh"; else if (w%2 == 0 && FileExists(sCar + "_wheel_left.mesh") ) sMesh = "_wheel_left.mesh"; else // 2- if (w%2 == 1 && FileExists(sCar + "_wheel_right.mesh")) sMesh = "_wheel_right.mesh"; if (FileExists(sCar + sMesh)) { String name = sDirname + sMesh; Entity* eWh = mSceneMgr->createEntity(siw, sDirname + sMesh, sCarI); if (ghost) { eWh->setRenderQueueGroup(g); eWh->setCastShadows(false); } ndWh[w]->attachObject(eWh); eWh->setVisibilityFlags(RV_Car); if (bLogInfo && (w==0 || w==2)) LogMeshInfo(eWh, name, 2); }else { ManualObject* mWh = pApp->CreateModel(mSceneMgr, sMtr[Mtr_CarBody]+siw, pCar ? &pCar->wheelmodelfront.mesh : 0, vPofs, true, false, siw); if (mWh) { if (ghost) { mWh->setRenderQueueGroup(g); mWh->setCastShadows(false); } ndWh[w]->attachObject(mWh); mWh->setVisibilityFlags(RV_Car); } } if (FileExists(sCar + "_brake.mesh") && !ghostTrk) { String name = sDirname + "_brake.mesh"; Entity* eBrake = mSceneMgr->createEntity(siw + "_brake", name, sCarI); if (ghost) { eBrake->setRenderQueueGroup(g); eBrake->setCastShadows(false); } ndBrake[w] = ndWh[w]->createChildSceneNode(); ndBrake[w]->attachObject(eBrake); eBrake->setVisibilityFlags(RV_Car); if (bLogInfo && w==0) LogMeshInfo(eBrake, name, 4); } } if (bLogInfo) // all LogO("MESH info: "+sDirname+"\t ALL sub: "+toStr(all_subs)+" tri: "+fToStr(all_tris/1000.f,1,4)+"k"); /// brake flares ++ ++ if (pCar) if (!brakePos.empty()) { SceneNode* nd = ndCar->createChildSceneNode(); brakes = mSceneMgr->createBillboardSet("Flr"+strI,2); brakes->setDefaultDimensions(brakeSize, brakeSize); brakes->setRenderQueueGroup(RQG_CarTrails); //brakes->setVisibilityFlags(); for (int i=0; i < brakePos.size(); ++i) brakes->createBillboard(brakePos[i], brakeClr); brakes->setVisible(false); brakes->setMaterialName("flare1"); nd->attachObject(brakes); } if (!ghostTrk) { // Particles //------------------------------------------------- /// world hit sparks if (!parHit) { parHit = mSceneMgr->createParticleSystem("Hit" + strI, "Sparks"); parHit->setVisibilityFlags(RV_Particles); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(parHit); parHit->getEmitter(0)->setEmissionRate(0); } /// boost emitters ------------------------ for (int i=0; i < 2; i++) { String si = strI + "_" +toStr(i); if (!parBoost[i]) { parBoost[i] = mSceneMgr->createParticleSystem("Boost"+si, sBoostParName); parBoost[i]->setVisibilityFlags(RV_Particles); if (!pSet->boostFromExhaust || !manualExhaustPos) { // no exhaust pos in car file, guess from bounding box Vector3 bsize = (bodyBox.getMaximum() - bodyBox.getMinimum())*0.5, bcenter = bodyBox.getMaximum() + bodyBox.getMinimum(); //LogO("Car body bbox : size " + toStr(bsize) + ", center " + toStr(bcenter)); Vector3 vp = bRotFix ? Vector3(bsize.z * 0.97, bsize.y * 0.65, bsize.x * 0.65 * (i==0 ? 1 : -1)) : Vector3(bsize.x * 0.97, bsize.y * 0.65, bsize.z * 0.65 * (i==0 ? 1 : -1)); //Vector3(1.9 /*back*/, 0.1 /*up*/, 0.6 * (i==0 ? 1 : -1)/*sides*/ vp.z *= boostSizeZ; vp += Vector3(boostOffset[0],boostOffset[1],boostOffset[2]); SceneNode* nb = pMainNode->createChildSceneNode(bcenter+vp); nb->attachObject(parBoost[i]); }else { // use exhaust pos values from car file Vector3 pos; if (i==0) pos = Vector3(exhaustPos[0], exhaustPos[1], exhaustPos[2]); else if (!has2exhausts) continue; else pos = Vector3(exhaustPos[0], exhaustPos[1], -exhaustPos[2]); SceneNode* nb = pMainNode->createChildSceneNode(pos); nb->attachObject(parBoost[i]); } parBoost[i]->getEmitter(0)->setEmissionRate(0); } } /// spaceship thrusters ^ ------------------------ if (!sThrusterPar.empty()) { int ii = thrusterSizeZ > 0.f ? 2 : 1; for (int i=0; i < ii; i++) { String si = strI + "_" +toStr(i); if (!parThrust[i]) { parThrust[i] = mSceneMgr->createParticleSystem("Thrust"+si, sThrusterPar); parThrust[i]->setVisibilityFlags(RV_Particles); Vector3 vp = Vector3(thrusterOfs[0],thrusterOfs[1], thrusterOfs[2] + (i-1)*2*thrusterSizeZ); SceneNode* nb = pMainNode->createChildSceneNode(vp); nb->attachObject(parThrust[i]); parThrust[i]->getEmitter(0)->setEmissionRate(0); } } } /// wheel emitters ------------------------ if (!ghost) { const static String sPar[PAR_ALL] = {"Smoke","Mud","Dust","FlWater","FlMud","FlMudS"}; // for ogre name // particle type names const String sName[PAR_ALL] = {sc->sParSmoke, sc->sParMud, sc->sParDust, "FluidWater", "FluidMud", "FluidMudSoft"}; for (int w=0; w < 4; ++w) { String siw = strI + "_" +toStr(w); // particles for (int p=0; p < PAR_ALL; ++p) if (!par[p][w]) { par[p][w] = mSceneMgr->createParticleSystem(sPar[p]+siw, sName[p]); par[p][w]->setVisibilityFlags(RV_Particles); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(par[p][w]); par[p][w]->getEmitter(0)->setEmissionRate(0.f); } // trails if (!ndWhE[w]) ndWhE[w] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); if (!whTrail[w]) { NameValuePairList params; params["numberOfChains"] = "1"; params["maxElements"] = toStr(320 * pSet->trails_len); whTrail[w] = (RibbonTrail*)mSceneMgr->createMovableObject("RibbonTrail", ¶ms); whTrail[w]->setInitialColour(0, 0.1,0.1,0.1, 0); whTrail[w]->setFaceCamera(false,Vector3::UNIT_Y); mSceneMgr->getRootSceneNode()->attachObject(whTrail[w]); whTrail[w]->setMaterialName("TireTrail"); whTrail[w]->setCastShadows(false); whTrail[w]->addNode(ndWhE[w]); } whTrail[w]->setTrailLength(90 * pSet->trails_len); //30 whTrail[w]->setInitialColour(0, 0.1f,0.1f,0.1f, 0); whTrail[w]->setColourChange(0, 0.0,0.0,0.0, /*fade*/0.08f * 1.f / pSet->trails_len); whTrail[w]->setInitialWidth(0, 0.f); } } UpdParsTrails(); } RecreateMaterials(); setMtrNames(); // this snippet makes sure the brake texture is pre-loaded. // since it is not used until you actually brake, we have to explicitely declare it ResourceGroupManager& resMgr = ResourceGroupManager::getSingleton(); if (FileExists(rCar + "_body00_brake.png")) resMgr.declareResource(sDirname + "_body00_brake.png", "Texture", resGrpId); if (FileExists(rCar + "_body00_add.png")) resMgr.declareResource(sDirname + "_body00_add.png", "Texture", resGrpId); // now just preload the whole resource group resMgr.initialiseResourceGroup(resGrpId); resMgr.loadResourceGroup(resGrpId); }