f32 TerrainTile::getVerticeHeight(vector3df pos) { f32 radius = 100; f32 returnvalue = 0; f32 smallest = radius; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); //Check all indices in the mesh to find the one that is nearest the position for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); pos.Y = realPos.Y; //Put the height at the same height //Check if its the smallest distance if((realPos.getDistanceFrom(pos) < smallest)) { smallest = realPos.getDistanceFrom(pos); returnvalue = realPos.Y; } } return returnvalue; }
ConvexHull::ConvexHull(ISceneNode *irrobject, double mass) :PhysicalObject(irrobject, mass) { IMeshBuffer* mbuffer = ((IAnimatedMeshSceneNode*)irrobject)->getMesh()->getMeshBuffer(0); int numVertices = mbuffer->getVertexCount(); btVector3 vertexBase[numVertices]; S3DVertex* vertices = (S3DVertex*)(mbuffer->getVertices()); vector3df scale = irrobject->getScale(); btConvexHullShape* chshape = new btConvexHullShape(); for(int i = 0; i < numVertices; i++) { vertexBase[i].setX((float)(vertices[i].Pos.X * scale.X)); vertexBase[i].setY((float)(vertices[i].Pos.Y * scale.Y)); vertexBase[i].setZ((float)(vertices[i].Pos.Z * scale.Z)); chshape->addPoint(vertexBase[i]); } initialize(chshape); }
CPlanarShadow::CPlanarShadow(scene::ISceneNode*parent, scene::ISceneManager *mgr, IMesh *mesh, float divisor) : ISceneNode(parent, mgr, -1), Vertices(0), Indices(0), SceneManager(mgr), Divisor(divisor), enableDepth(false) { s32 i; s32 totalVertices = 0; s32 totalIndices = 0; s32 bufcnt = mesh->getMeshBufferCount(); IMeshBuffer* b; for (i=0; i<bufcnt; ++i) { b = mesh->getMeshBuffer(i); totalIndices += b->getIndexCount(); totalVertices += b->getVertexCount(); } Vertices = new core::vector3df[totalVertices]; Indices = new u16[totalIndices]; int indStart = 0, vtxNow = 0; for (i=0; i < bufcnt; ++i) { b = mesh->getMeshBuffer(i); u16* buff = b->getIndices(); for (int o = 0; o < b->getIndexCount(); o++) { Indices[indStart++] = buff[o] + vtxNow; } vtxNow += b->getVertexCount(); } VertexCount = totalVertices; IndexCount = totalIndices; buildMesh(mesh); }
void TerrainTile::mergeToTile(TerrainTile* tile) { if(!tile || custom) { #ifdef DEBUG cout << "DEBUG : TERRAIN TILE : MERGE FAILED, TILE IS NULL: " << endl; #endif return; } else { IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); IMeshBuffer* neighborBuffer = tile->getMeshBuffer(); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); S3DVertex* n_mb_vertices = (S3DVertex*) neighborBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); u16* n_mb_indices = neighborBuffer->getIndices(); for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { for (unsigned int i = 0; i < neighborBuffer->getVertexCount(); i += 1) { vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); vector3df nRealPos = n_mb_vertices[i].Pos*(scale/nodescale) + tile->getNode()->getPosition(); if((realPos.X == nRealPos.X) && (realPos.Z == nRealPos.Z)) { mb_vertices[j].Pos.Y = n_mb_vertices[i].Pos.Y; mb_vertices[j].Normal = n_mb_vertices[i].Normal; //New Copy the normal information needrecalc=true; } } } //smgr->getMeshManipulator()->recalculateNormals(((IMeshSceneNode*)node)->getMesh(),true); ((IMeshSceneNode*)node)->getMesh()->setDirty(); needrecalc = true; } }
// Test the tile if it was being modified bool TerrainTile::checkModified() { bool modified = false; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); if(realPos.Y != 0.0f ) { modified = true; j=meshBuffer->getVertexCount(); break; } } return modified; }
void TerrainTile::transformMeshToValue(vector3df clickPos, f32 radius, f32 radius2, f32 strength, f32 value, bool norecalc) { if (custom) return; if(strength<0) strength = -strength; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < radius) { needrecalc=true; //f32 ratio = sin(radius - realPos.getDistanceFrom(clickPos)); f32 ratio = radius; if (radius2-realPos.getDistanceFrom(clickPos)<0) ratio = (radius+radius2)-realPos.getDistanceFrom(clickPos); if(mb_vertices[j].Pos.Y > value) { //mb_vertices[j].Pos.Y -= strength * ratio / (scale/nodescale); mb_vertices[j].Pos.Y -= strength * ratio / (scale/nodescale); if(mb_vertices[j].Pos.Y <= value) mb_vertices[j].Pos.Y = value; } if(mb_vertices[j].Pos.Y < value) { //mb_vertices[j].Pos.Y += strength * ratio / (scale / nodescale); mb_vertices[j].Pos.Y += strength *ratio / (scale / nodescale); if(mb_vertices[j].Pos.Y >= value) mb_vertices[j].Pos.Y = value; } } } if (norecalc) { recalculate(true); } else recalculate(); }
void TerrainTile::storeUndo() { IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*)meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { undobuffer.push_back(mb_vertices[j].Pos.Y); } undohistory.push_back(undobuffer); undobuffer.clear(); }
void TerrainTile::transformMesh(vector3df clickPos, f32 radius, f32 radius2, f32 strength, bool norecalc) { if (custom) return; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < radius) { needrecalc=true; // This will flag the tile since it's in the radius and will modify the tile vertices. //f32 ratio = sin(radius - realPos.getDistanceFrom(clickPos)); //- (realPos.getDistanceFrom(clickPos)-radius2) f32 ratio = radius; if (radius2-realPos.getDistanceFrom(clickPos)<0) ratio = (radius+radius2)-realPos.getDistanceFrom(clickPos); mb_vertices[j].Pos.Y += (strength * (ratio)/(scale/nodescale)); //printf("found something here: vertice %i, vertice Y: %f\n",j, mb_vertices[j].Pos.Y); } //if(mb_vertices[j].Pos.Y > nodescale/4) mb_vertices[j].Pos.Y = nodescale/4; // Fix up/down limits if(mb_vertices[j].Pos.Y > nodescale*0.75f) mb_vertices[j].Pos.Y = nodescale*0.75f; if(mb_vertices[j].Pos.Y < -(nodescale*0.25f)) mb_vertices[j].Pos.Y = -(nodescale*0.25f); } if (norecalc) { recalculate(true); } else recalculate(); }
btSoftBody* MeshTools::createSoftBodyFromMesh(btSoftBodyWorldInfo& worldInfo, IMesh* mesh) { IMeshBuffer* buffer = mesh->getMeshBuffer(0); vector<btScalar> vertices; for (unsigned int i=0; i < buffer->getVertexCount(); ++i) { vector3df p = getBaseVertex(buffer, i).Pos; vertices.push_back(p.X); vertices.push_back(p.Y); vertices.push_back(p.Z); } vector<int> triangles; for (unsigned int i=0; i < buffer->getIndexCount(); ++i) triangles.push_back(buffer->getIndices()[i]); auto result = btSoftBodyHelpers::CreateFromTriMesh(worldInfo, &vertices[0], &triangles[0], buffer->getIndexCount()/3, false); result->m_bUpdateRtCst = true; return result; }
void CPlanarShadow::buildMesh(IMesh*mesh) { s32 i; s32 totalVertices = 0; s32 totalIndices = 0; s32 bufcnt = mesh->getMeshBufferCount(); IMeshBuffer* b; int vtxNow = 0; for (i=0; i<bufcnt; ++i) { IMeshBuffer* b; b = mesh->getMeshBuffer(i); video::S3DVertex* vtxbuff = (video::S3DVertex*)b->getVertices(); for(int o = 0; o < b->getVertexCount(); o++) Vertices[vtxNow++] = vtxbuff[o].Pos; } }
//! creates the tree bool COctTreeSceneNode::createTree(IMesh* mesh) { if (!mesh) return false; MeshName = SceneManager->getMeshCache()->getMeshFilename( mesh ); deleteTree(); u32 beginTime = os::Timer::getRealTime(); u32 nodeCount = 0; u32 polyCount = 0; Box = mesh->getBoundingBox(); if (mesh->getMeshBufferCount()) { vertexType = mesh->getMeshBuffer(0)->getVertexType(); switch(vertexType) { case video::EVT_STANDARD: { for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { IMeshBuffer* b = mesh->getMeshBuffer(i); if (b->getVertexCount() && b->getIndexCount()) { Materials.push_back(b->getMaterial()); StdMeshes.push_back(OctTree<video::S3DVertex>::SMeshChunk()); OctTree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast(); nchunk.MaterialId = Materials.size() - 1; u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; v<b->getVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); polyCount += b->getIndexCount(); nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; v<b->getIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } StdOctTree = new OctTree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode); nodeCount = StdOctTree->getNodeCount(); } break; case video::EVT_2TCOORDS: { for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { IMeshBuffer* b = mesh->getMeshBuffer(i); if (b->getVertexCount() && b->getIndexCount()) { Materials.push_back(b->getMaterial()); LightMapMeshes.push_back(OctTree<video::S3DVertex2TCoords>::SMeshChunk()); OctTree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast(); nchunk.MaterialId = Materials.size() - 1; u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; v<b->getVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); polyCount += b->getIndexCount(); nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; v<b->getIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } LightMapOctTree = new OctTree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode); nodeCount = LightMapOctTree->getNodeCount(); } break; case video::EVT_TANGENTS: { for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { IMeshBuffer* b = mesh->getMeshBuffer(i); if (b->getVertexCount() && b->getIndexCount()) { Materials.push_back(b->getMaterial()); TangentsMeshes.push_back(OctTree<video::S3DVertexTangents>::SMeshChunk()); OctTree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast(); nchunk.MaterialId = Materials.size() - 1; u32 v; nchunk.Vertices.reallocate(b->getVertexCount()); for (v=0; v<b->getVertexCount(); ++v) nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); polyCount += b->getIndexCount(); nchunk.Indices.reallocate(b->getIndexCount()); for (v=0; v<b->getIndexCount(); ++v) nchunk.Indices.push_back(b->getIndices()[v]); } } TangentsOctTree = new OctTree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode); nodeCount = TangentsOctTree->getNodeCount(); } break; } } u32 endTime = os::Timer::getRealTime(); c8 tmp[255]; sprintf(tmp, "Needed %ums to create OctTree SceneNode.(%u nodes, %u polys)", endTime - beginTime, nodeCount, polyCount/3); os::Printer::log(tmp, ELL_INFORMATION); return true; }
//! writes a mesh bool COBJMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) { if (!file) return false; os::Printer::log("Writing mesh", file->getFileName()); // write OBJ MESH header const core::stringc name(FileSystem->getFileBasename(SceneManager->getMeshCache()->getMeshName(mesh), false)+".mtl"); file->write("# exported by Irrlicht\n",23); file->write("mtllib ",7); file->write(name.c_str(),name.size()); file->write("\n\n",2); // write mesh buffers core::array<video::SMaterial*> mat; u32 allVertexCount=1; // count vertices over the whole file for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { core::stringc num(i+1); IMeshBuffer* buffer = mesh->getMeshBuffer(i); if (buffer && buffer->getVertexCount()) { file->write("g grp", 5); file->write(num.c_str(), num.size()); file->write("\n",1); u32 j; const u32 vertexCount = buffer->getVertexCount(); for (j=0; j<vertexCount; ++j) { file->write("v ",2); getVectorAsStringLine(buffer->getPosition(j), num); file->write(num.c_str(), num.size()); } for (j=0; j<vertexCount; ++j) { file->write("vt ",3); getVectorAsStringLine(buffer->getTCoords(j), num); file->write(num.c_str(), num.size()); } for (j=0; j<vertexCount; ++j) { file->write("vn ",3); getVectorAsStringLine(buffer->getNormal(j), num); file->write(num.c_str(), num.size()); } file->write("usemtl mat",10); num = ""; for (j=0; j<mat.size(); ++j) { if (*mat[j]==buffer->getMaterial()) { num = core::stringc(j); break; } } if (num == "") { num = core::stringc(mat.size()); mat.push_back(&buffer->getMaterial()); } file->write(num.c_str(), num.size()); file->write("\n",1); const u32 indexCount = buffer->getIndexCount(); for (j=0; j<indexCount; j+=3) { file->write("f ",2); num = core::stringc(buffer->getIndices()[j+2]+allVertexCount); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write(" ",1); num = core::stringc(buffer->getIndices()[j+1]+allVertexCount); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write(" ",1); num = core::stringc(buffer->getIndices()[j+0]+allVertexCount); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write("/",1); file->write(num.c_str(), num.size()); file->write(" ",1); file->write("\n",1); } file->write("\n",1); allVertexCount += vertexCount; } } if (mat.size() == 0) return true; file = FileSystem->createAndWriteFile( name ); if (file) { os::Printer::log("Writing material", file->getFileName()); file->write("# exported by Irrlicht\n\n",24); for (u32 i=0; i<mat.size(); ++i) { core::stringc num(i); file->write("newmtl mat",10); file->write(num.c_str(),num.size()); file->write("\n",1); getColorAsStringLine(mat[i]->AmbientColor, "Ka", num); file->write(num.c_str(),num.size()); getColorAsStringLine(mat[i]->DiffuseColor, "Kd", num); file->write(num.c_str(),num.size()); getColorAsStringLine(mat[i]->SpecularColor, "Ks", num); file->write(num.c_str(),num.size()); getColorAsStringLine(mat[i]->EmissiveColor, "Ke", num); file->write(num.c_str(),num.size()); num = core::stringc(mat[i]->Shininess/0.128f); file->write("Ns ", 3); file->write(num.c_str(),num.size()); file->write("\n", 1); if (mat[i]->getTexture(0)) { file->write("map_Kd ", 7); file->write(mat[i]->getTexture(0)->getName().getPath().c_str(), mat[i]->getTexture(0)->getName().getPath().size()); file->write("\n",1); } file->write("\n",1); } file->drop(); } return true; }
// ISoftBody::createShape() is taken from code found on the Irrlicht forum void ISoftBody::createShape(IMesh* const collMesh) { int cMeshBuffer, j; IMeshBuffer *mb; video::S3DVertex* mb_vertices; u16* mb_indices; std::map<int, int> index_map; std::map<int, int> bullet_map; std::map<int, S3DVertex> vertex_map; int count = 0; indexCount = 0; vertexCount = 0; for(cMeshBuffer=0; cMeshBuffer < 1; cMeshBuffer++) { //printf("Loading new mesh buffer for softbody.\n"); mb = collMesh->getMeshBuffer(cMeshBuffer); mb_vertices = (irr::video::S3DVertex*)mb->getVertices(); mb_indices = mb->getIndices(); indexCount += mb->getIndexCount(); vertexCount += mb->getVertexCount(); for(u32 i=0; i<mb->getIndexCount(); i++) { int iIndex = mb_indices[i]; vector3df iVertex = mb_vertices[iIndex].Pos; bool isFirst = true; for(u32 j=0; j<i; j++) { int jIndex = mb_indices[j]; vector3df jVertex = mb_vertices[jIndex].Pos; if (iVertex == jVertex) { index_map.insert(std::make_pair(i, j)); isFirst = false; break; } } // ???????Bullet??Index?????? if(isFirst) { // Irrlicht?Index??????Index index_map.insert(std::make_pair(i, i)); // ?????Index????Index bullet_map.insert(std::make_pair(i, count)); // ??Index????????? vertex_map.insert(std::make_pair(count, mb_vertices[iIndex])); count++; } } } indices = new int[indexCount]; vertexCount = vertex_map.size(); vertices = new btScalar[vertexCount*3]; for(j=0; j<indexCount; j++) { int index1 = index_map.find(j)->second; int index2 = bullet_map.find(index1)->second; indices[j] = index2; } for(j=0; j<vertexCount; j++) { vertices[3*j] = vertex_map[j].Pos.X; vertices[3*j+1] = vertex_map[j].Pos.Y; vertices[3*j+2] = -vertex_map[j].Pos.Z; } //std::cout << "create softbody" << std::endl; object = btSoftBodyHelpers::CreateFromTriMesh( dynamicsWorld->getSoftBodyWorldInfo(), vertices,indices, indexCount/3); //std::cout << "create map" << std::endl; for(int i=0; i<getPointer()->m_faces.size(); i++) { btSoftBody::Face face = getPointer()->m_faces[i]; for(int j=0; j<3; j++) { if(node_map.find(face.m_n[j]) == node_map.end()) { node_map.insert(std::make_pair(face.m_n[j], node_map.size())); } } for(int j=0; j<3; j++) { m_indices.push_back(node_map.find(face.m_n[j])->second); } } // Reverse node->index to index->node (should be unique on both sides) std::map<btSoftBody::Node*, int>::const_iterator node_iter; for(node_iter = node_map.begin(); node_iter != node_map.end(); ++node_iter) { m_vertices.insert(std::make_pair(node_iter->second, node_iter->first)); } //std::cout << "update Irrlicht vertices" << std::endl; std::map<int, btSoftBody::Node*>::const_iterator it; for(u32 i=0; i<mb->getVertexCount(); i++) { for(it=m_vertices.begin(); it != m_vertices.end(); ++it) { int v_index = it->first; btSoftBody::Node* node = it->second; if(node->m_x.x() == mb_vertices[i].Pos.X && node->m_x.y() == mb_vertices[i].Pos.Y && node->m_x.z() == mb_vertices[i].Pos.Z) { MeshMap.insert(std::make_pair(i, v_index)); break; } } } }
Vegetation* TerrainTile::paintVegetation(vector3df clickPos, bool erase) { //Do a prior check to see if there is a least one tree active in the list of active objects vector<bool> enabled=VegetationSeed::getInstance()->getEnabled(); vector<int> newlist; for(int i = 0; i<(int)enabled.size(); i++) { if (enabled[i]==true) newlist.push_back(i); //New list will contain the list of the enabled items } if (newlist.size()==0) return NULL; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); Vegetation* returnvalue = NULL; for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { if(erase) { vector3df realPos = vector3df (0.0f,0.0f,0.0f); //Should be able to place a tree anywhere on a custom model if (!custom) realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); else realPos = clickPos; clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < vegetationRange/2 && getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z))) { Vegetation* toRemove = getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z)); returnvalue = toRemove; return returnvalue; // Done outside the function (caller will do the removal) } } else { vector3df realPos = vector3df (0.0f,0.0f,0.0f); //Should be able to place a tree anywhere on a custom model if (!custom) realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); else realPos = clickPos; clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < (vegetationRange/2) && !getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z))) { Vegetation* v = new Vegetation(); //v->setPosition(vector3df(realPos.X + (rand()%5)*0.1f - 0.25f,realPos.Y/(scale/nodescale),realPos.Z + (rand()%5)*0.1f - 0.25f)); //v->setPosition(vector3df(realPos.X + (rand()%5)*scale/100,realPos.Y,realPos.Z + (rand()%5)*scale/100)); v->setPosition(vector3df(realPos.X,realPos.Y,realPos.Z)); f32 treesize = (f32)(rand() % 50 + 25); f32 treerot = (f32)(rand() % 1 + 359); v->setScale(vector3df(treesize,treesize,treesize)); v->setRotation(vector3df(0,treerot,0)); #ifdef DEBUG printf("Attempting to place a tree with this size: %f\n",treesize); #endif vegetationVector.push_back(v); returnvalue = v; return returnvalue; #ifdef APP_DEBUG cout << "DEBUG : TERRAIN TILE : VEGETATION CREATED: " << realPos.X << "," << realPos.Y << "," << realPos.Z << " TOTAL:" << vegetationVector.size() << endl; #endif } } } return returnvalue; }
//! draws the element and its children void CGUIMeshViewer::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); IVideoDriver* driver = Environment->getVideoDriver(); rect<SINT32> viewPort = AbsoluteRect; viewPort.LowerRightCorner.x -= 1; viewPort.LowerRightCorner.y -= 1; viewPort.UpperLeftCorner.x += 1; viewPort.UpperLeftCorner.y += 1; viewPort.clipAgainst(AbsoluteClippingRect); // draw the frame rect<SINT32> frameRect(AbsoluteRect); frameRect.LowerRightCorner.y = frameRect.UpperLeftCorner.y + 1; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); frameRect.LowerRightCorner.y = AbsoluteRect.LowerRightCorner.y; frameRect.LowerRightCorner.x = frameRect.UpperLeftCorner.x + 1; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); frameRect = AbsoluteRect; frameRect.UpperLeftCorner.x = frameRect.LowerRightCorner.x - 1; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); frameRect = AbsoluteRect; frameRect.UpperLeftCorner.y = AbsoluteRect.LowerRightCorner.y - 1; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); // draw the mesh if (Mesh) { //TODO: if outside of screen, dont draw. // - why is the absolute clipping rect not already the screen? rect<SINT32> oldViewPort = driver->getViewPort(); driver->setViewPort(viewPort); Matrix4 mat; //CameraControl->calculateProjectionMatrix(mat); //driver->setTransform(TS_PROJECTION, mat); mat = Matrix4::IDENTITY; mat.setTrans(Vector3(0, 0, 0)); //mat.setTranslation(Vector3(0, 0, 0)); driver->setTransform(ETS_WORLD, mat); //CameraControl->calculateViewMatrix(mat); //driver->setTransform(TS_VIEW, mat); driver->setMaterial(Material); UINT32 frame = 0; if (Mesh->getFrameCount()) frame = (Timer::getTime() / 20) % Mesh->getFrameCount(); const IMesh* const m = Mesh->getMesh(frame); for (UINT32 i = 0; i<m->getMeshBufferCount(); ++i) { IMeshBuffer* mb = m->getMeshBuffer(i); driver->drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount() / 3, mb->getVertexType(), EPT_TRIANGLES, mb->getIndexType()); } driver->setViewPort(oldViewPort); } IGUIElement::draw(); }
//! sets the mesh from which the shadow volume should be generated. void CShadowVolumeSceneNode::setMeshToRenderFrom(IMesh* mesh) { ShadowVolumesUsed = 0; s32 oldIndexCount = IndexCount; s32 oldVertexCount = VertexCount; VertexCount = 0; IndexCount = 0; if (!mesh) return; // calculate total amount of vertices and indices u32 i; s32 totalVertices = 0; s32 totalIndices = 0; u32 bufcnt = mesh->getMeshBufferCount(); IMeshBuffer* b; for (i=0; i<bufcnt; ++i) { b = mesh->getMeshBuffer(i); totalIndices += b->getIndexCount(); totalVertices += b->getVertexCount(); } // allocate memory if nececcary if (totalVertices > VertexCountAllocated) { delete [] Vertices; Vertices = new core::vector3df[totalVertices]; VertexCountAllocated = totalVertices; } if (totalIndices > IndexCountAllocated) { delete [] Indices; Indices = new u16[totalIndices]; IndexCountAllocated = totalIndices; if (UseZFailMethod) { delete [] FaceData; FaceData = new bool[totalIndices / 3]; } } // copy mesh for (i=0; i<bufcnt; ++i) { b = mesh->getMeshBuffer(i); s32 idxcnt = b->getIndexCount(); s32 vtxnow = VertexCount; const u16* idxp = b->getIndices(); const u16* idxpend = idxp + idxcnt; for (; idxp!=idxpend; ++idxp) Indices[IndexCount++] = *idxp + vtxnow; s32 vtxcnt = b->getVertexCount(); switch(b->getVertexType()) { case video::EVT_STANDARD: { const video::S3DVertex* vp = (video::S3DVertex*)b->getVertices(); const video::S3DVertex* vpend = vp + vtxcnt; for (; vp!=vpend; ++vp) Vertices[VertexCount++] = (*vp).Pos; } break; case video::EVT_2TCOORDS: { const video::S3DVertex2TCoords* vp = (video::S3DVertex2TCoords*)b->getVertices(); const video::S3DVertex2TCoords* vpend = vp + vtxcnt; for (; vp!=vpend; ++vp) Vertices[VertexCount++] = (*vp).Pos; } break; case video::EVT_TANGENTS: { const video::S3DVertexTangents* vp = (video::S3DVertexTangents*)b->getVertices(); const video::S3DVertexTangents* vpend = vp + vtxcnt; for (; vp!=vpend; ++vp) Vertices[VertexCount++] = (*vp).Pos; } break; } } // recalculate adjacency if neccessarry if (oldVertexCount != VertexCount && oldIndexCount != IndexCount && UseZFailMethod) calculateAdjacency(); // create as much shadow volumes as there are lights but // do not ignore the max light settings. u32 lights = SceneManager->getVideoDriver()->getDynamicLightCount(); core::matrix4 mat = Parent->getAbsoluteTransformation(); core::vector3df parentpos = Parent->getAbsolutePosition(); core::vector3df lpos; mat.makeInverse(); for (i=0; i<lights; ++i) { const video::SLight& dl = SceneManager->getVideoDriver()->getDynamicLight(i); lpos = dl.Position; if (dl.CastShadows && fabs((lpos - parentpos).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f)) { mat.transformVect(lpos); createShadowVolume(lpos); } } }