ISimpleMesh* CResourceFactory::createSimpleMesh( const std::string& name, u32 sortcode, u32 vertexFormat, void* vertices, void* indices, u32 vertexCount, u32 vertexStride, u32 indiceCount, const math::SAxisAlignedBox& aabb, bool bit32Index, E_MEMORY_USAGE usage) { IMeshBuffer* buffer = createMeshBuffer(usage, vertices, indices, vertexCount, indiceCount, vertexStride, bit32Index); if (!buffer) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str()); return nullptr; } CSimpleMesh* mesh = new CSimpleMesh(name, sortcode, aabb, vertexFormat, buffer); if (!mesh) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str()); buffer->drop(); return nullptr; } return mesh; }
void CTriangleSelector::updateFromMesh(const IMesh* mesh) const { if (!mesh) return; u32 meshBuffers = mesh->getMeshBufferCount(); u32 triangleCount = 0; BoundingBox.reset(0.f, 0.f, 0.f); for (u32 i = 0; i < meshBuffers; ++i) { IMeshBuffer* buf = mesh->getMeshBuffer(i); u32 idxCnt = buf->getIndexCount(); const u16* indices = buf->getIndices(); for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df& tri = Triangles[triangleCount++]; tri.pointA = buf->getPosition(indices[index + 0]); tri.pointB = buf->getPosition(indices[index + 1]); tri.pointC = buf->getPosition(indices[index + 2]); BoundingBox.addInternalPoint(tri.pointA); BoundingBox.addInternalPoint(tri.pointB); BoundingBox.addInternalPoint(tri.pointC); } } }
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); }
float CGWIC_Cell::GetTerrainHeightUnderPointMetric(irr::core::vector3df pnt) { u32 x = floor(pnt.X); u32 z = floor(pnt.Z); if (x > 255) x = 255; if (z > 255) z = 255; u32 index = x * 256 + z; IMesh* pMesh = terrain->getMesh(); float res = 0.f; // float max = 0; const float scy = terrain->getScale().Y; //FIXME: get the true position in meters for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) { IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n); if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue; S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices(); res = pVertices[index].Pos.Y / scy; // res = (pVertices[index].Pos.Y + terrain->getPosition().Y) / scy; // res += terrain->getPosition().Y / GWIC_IRRUNITS_PER_METER; // std::cerr << "POSIT " << res << std::endl; // for (u32 k=0; k<(256*256); k++) if (pVertices[k].Pos.Y > max) max = pVertices[k].Pos.Y; // std::cerr << "MAXX " << max << std::endl; break; } return res; }
void CGWIC_Cell::RandomizeTerrain(float subdelta) { IMesh* pMesh = terrain->getMesh(); s32 Q = static_cast<s32> (subdelta); for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) { IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n); if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue; S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices(); //1. find the current max & min, since we don't want to escalate landscape float max = 0; float min = 256; u32 i; for (i=0; i<(256*256); i++) { if (pVertices[i].Pos.Y < min) min = pVertices[i].Pos.Y; if (pVertices[i].Pos.Y > max) max = pVertices[i].Pos.Y; } std::cout << "RandTerr: min=" << min << "; max=" << max << std::endl; //2. create temp array & randomize it std::vector<float> tmparr; float cy; for (i=0; i<(256*256); i++) { if (Q) { cy = Random_FLOAT(max-min); cy += min; } else cy = 0; tmparr.push_back(cy); } std::cout << std::endl; //3. interpolate vertices inside big quads s32 A = 0; if (Q) A = 256 / Q + 1; for (int qx=0; qx<A; qx++) for (int qy=0; qy<A; qy++) { //TODO: remove unnecessary vars int x0 = qx * Q; int y0 = qy * Q; int xe = x0 + Q; if (xe > 255) xe = 255; int ye = y0 + Q; if (ye > 255) ye = 255; float hx0 = tmparr[x0*256+y0]; float hy0 = (qx%2)? tmparr[xe*256+ye]:hx0; float hxe = tmparr[xe*256+y0]; float hye = tmparr[x0*256+ye]; float lhy = hye - hy0; float lhx = hxe - hx0; for (int cx=x0; cx<xe; cx++) for (int cy=y0; cy<ye; cy++) { float ch = (((qx%2)?(x0-cx):(cx-x0))/lhx)*lhx+hx0; ch += (((qy%2)?(y0-cy):(cy-y0))/lhy)*lhy+hy0; tmparr[cx*256+cy] = ch / 2; } } //4. get result back for (i=0; i<(256*256); i++) pVertices[i].Pos.Y = tmparr[i]; break; } TerrainChanged(); }
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; }
//! reads a mesh sections and creates a mesh from it IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) { SAnimatedMesh* animatedmesh = new SAnimatedMesh(); SMesh* mesh = new SMesh(); animatedmesh->addMesh(mesh); mesh->drop(); core::stringc bbSectionName = "boundingBox"; core::stringc bufferSectionName = "buffer"; core::stringc meshSectionName = "mesh"; if (!reader->isEmptyElement()) while(reader->read()) { if (reader->getNodeType() == io::EXN_ELEMENT) { const wchar_t* nodeName = reader->getNodeName(); if (bbSectionName == nodeName) { // inside a bounding box, ignore it for now because // we are calculating this anyway ourselves later. } else if (bufferSectionName == nodeName) { // we've got a mesh buffer IMeshBuffer* buffer = readMeshBuffer(reader); if (buffer) { mesh->addMeshBuffer(buffer); buffer->drop(); } } else skipSection(reader, true); // unknown section } // end if node type is element else if (reader->getNodeType() == io::EXN_ELEMENT_END) { if (meshSectionName == reader->getNodeName()) { // end of mesh section reached, cancel out break; } } } // end while reader->read(); mesh->recalculateBoundingBox(); animatedmesh->recalculateBoundingBox(); return animatedmesh; }
//----------------------------------------------------------------------- // e x t r a c t T r i a n g l e s //----------------------------------------------------------------------- btTriangleMesh* TMeshShape::extractTriangles(IMesh* mesh, bool removeDupVertices) { vector3df p1, p2, p3; // 32 bit indices, 3 component vertices - allows for use in decomposition. btTriangleMesh* triMesh = new btTriangleMesh(true, false); u32 bufCount = mesh->getMeshBufferCount(); for(u32 i=0;i<bufCount;i++) { IMeshBuffer* mbuf = mesh->getMeshBuffer(i); void* vp = mbuf->getVertices(); E_VERTEX_TYPE vtype = mbuf->getVertexType(); S3DVertex *vstd = (S3DVertex*) vp; S3DVertex2TCoords *v2t = (S3DVertex2TCoords*) vp; S3DVertexTangents *vtan = (S3DVertexTangents*)vp; const u16* ip = mbuf->getIndices(); u32 ic = mbuf->getIndexCount(); u32 fi = 0; while(fi < ic) { S3DVertex *v1,*v2,*v3; switch(vtype) { case EVT_2TCOORDS: v1 = &v2t[ip[fi++]]; v2 = &v2t[ip[fi++]]; v3 = &v2t[ip[fi++]]; break; case EVT_TANGENTS: v1 = &vtan[ip[fi++]]; v2 = &vtan[ip[fi++]]; v3 = &vtan[ip[fi++]]; break; default: v1 = &vstd[ip[fi++]]; v2 = &vstd[ip[fi++]]; v3 = &vstd[ip[fi++]]; break; } p1 = v1->Pos; p2 = v2->Pos; p3 = v3->Pos; btVector3 b1(p1.X, p1.Y, p1.Z); btVector3 b2(p2.X, p2.Y, p2.Z); btVector3 b3(p3.X, p3.Y, p3.Z); triMesh->addTriangle(b1,b2,b3,removeDupVertices); } } return triMesh; }
//! Sets a new mesh void CInstancedMeshSceneNode::setMesh(IMesh* mesh) { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if (baseMesh) { baseMesh->drop(); baseMesh = NULL; } if (mesh) { mesh->grab(); baseMesh = mesh; IMeshBuffer* renderBuffer = baseMesh->getMeshBuffer(0); while (renderBuffer->getVertexBufferCount() > 1) renderBuffer->removeVertexBuffer(1); // TODO add getter and so that the smaller value isnt erased // maybe the func isnt longer needed so delete it driver->setMinHardwareBufferVertexCount(renderBuffer->getVertexBuffer()->getVertexCount()); renderBuffer->setHardwareMappingHint(scene::EHM_STATIC); video::IVertexDescriptor* index = SceneManager->getVideoDriver()->getVertexDescriptor("BaseInstanceIndex"); if (!index) { video::IVertexDescriptor* stdv = SceneManager->getVideoDriver()->getVertexDescriptor(0); index = SceneManager->getVideoDriver()->addVertexDescriptor("BaseInstanceIndex"); for (u32 i = 0; i < stdv->getAttributeCount(); ++i) { index->addAttribute(stdv->getAttribute(i)->getName(), stdv->getAttribute(i)->getElementCount(), stdv->getAttribute(i)->getSemantic(), stdv->getAttribute(i)->getType(), stdv->getAttribute(i)->getBufferID()); } index->addAttribute("InstancingMatrix1", 4, video::EVAS_TEXCOORD1, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix2", 4, video::EVAS_TEXCOORD2, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix3", 4, video::EVAS_TEXCOORD3, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix4", 4, video::EVAS_TEXCOORD4, video::EVAT_FLOAT, 1); index->setInstanceDataStepRate(video::EIDSR_PER_INSTANCE, 1); } IVertexBuffer* instanceBuffer = new CVertexBuffer<core::matrix4>(); renderBuffer->setVertexDescriptor(index); renderBuffer->addVertexBuffer(instanceBuffer); renderBuffer->getVertexBuffer(0)->setHardwareMappingHint(scene::EHM_STATIC); renderBuffer->getVertexBuffer(1)->setHardwareMappingHint(scene::EHM_STATIC); renderBuffer->getIndexBuffer()->setHardwareMappingHint(scene::EHM_STATIC); instanceBuffer->drop(); } }
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(); }
//! Sets a new mesh void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh) { if (!mesh) return; // won't set null mesh if (Mesh != mesh) { if (Mesh) Mesh->drop(); Mesh = mesh; // grab the mesh (it's non-null!) Mesh->grab(); } // get materials and bounding box Box = Mesh->getBoundingBox(); IMesh* m = Mesh->getMesh(0,0); if (m) { Materials.clear(); Materials.reallocate(m->getMeshBufferCount()); for (u32 i=0; i<m->getMeshBufferCount(); ++i) { IMeshBuffer* mb = m->getMeshBuffer(i); if (mb) Materials.push_back(mb->getMaterial()); else Materials.push_back(video::SMaterial()); } } // clean up joint nodes if (JointsUsed) { JointsUsed=false; checkJoints(); } // get start and begin time // setAnimationSpeed(Mesh->getAnimationSpeed()); setFrameLoop(0, Mesh->getFrameCount()); }
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(); }
void CInstancedMeshSceneNode::updateInstances() { if (!baseMesh || baseMesh->getMeshBuffer(0)->getVertexBufferCount() != 2) return; IMeshBuffer* renderBuffer = baseMesh->getMeshBuffer(0); box.reset(0, 0, 0); const u32 size = instanceNodeArray.size(); renderBuffer->getVertexBuffer(1)->clear(); renderBuffer->getVertexBuffer(1)->setDirty(); renderBuffer->getVertexBuffer(1)->set_used(size); for (u32 i = 0; i < size; ++i) { core::aabbox3df instanceBox = renderBuffer->getBoundingBox(); instanceNodeArray[i]->getAbsoluteTransformation().transformBoxEx(instanceBox); if (!SceneManager->isCulled(instanceNodeArray[i])) renderBuffer->getVertexBuffer(1)->setVertex(i, &instanceNodeArray[i]->getAbsoluteTransformation()); box.addInternalPoint(instanceNodeArray[i]->getAbsolutePosition()); } renderBuffer->getVertexBuffer(1)->setDirty(); }
void CMeshSceneNode::copyMaterials() { Materials.clear(); if (Mesh) { video::SMaterial mat; for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i) { IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (mb) mat = mb->getMaterial(); Materials.push_back(mat); } } }
bool CGWIC_Cell::SetTerrainHeightUnderPointMetric(irr::core::vector3df pnt, float height, bool update) { u32 x = floor(pnt.X); u32 z = floor(pnt.Z); if (x > 255) x = 255; if (z > 255) z = 255; u32 index = x * 256 + z; IMesh* pMesh = terrain->getMesh(); const float scy = terrain->getScale().Y; for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) { IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n); if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue; S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices(); pVertices[index].Pos.Y = height * scy; break; } if (update) TerrainChanged(); return true; }
void TerrainTile::restoreUndo() { if (undohistory.size()>0) { IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*)meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); printf("Here is the undo history size: %i\n", undohistory.size()); undobuffer = undohistory.back(); printf("Here is the undo buffer size: %i\n", undobuffer.size()); for (unsigned int j = 0; j < undohistory[undohistory.size()-1].size(); j += 1) { mb_vertices[j].Pos.Y = undohistory[undohistory.size() - 1][j]; } meshBuffer = ((IMeshSceneNode*)ocean)->getMesh()->getMeshBuffer(0); mb_vertices = (S3DVertex*)meshBuffer->getVertices(); mb_indices = meshBuffer->getIndices(); for (unsigned int j = 0; j < undohistory[undohistory.size() - 1].size(); j += 1) { mb_vertices[j].Pos.Y = undohistory[undohistory.size() - 1][j]; } needrecalc = true; recalculate(); undohistory.pop_back(); //Remove the last element of the vector by 1; undobuffer.clear(); //Clear the buffer; } }
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; }
// 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 CTriangleSelector::updateFromMesh(const IMesh* mesh) const { if (!mesh) return; u32 meshBuffers = mesh->getMeshBufferCount(); u32 triangleCount = 0; for (u32 i = 0; i < meshBuffers; ++i) { IMeshBuffer* buf = mesh->getMeshBuffer(i); u32 idxCnt = buf->getIndexCount(); const u16* indices = buf->getIndices(); switch (buf->getVertexType()) { case video::EVT_STANDARD: { video::S3DVertex* vtx = (video::S3DVertex*)buf->getVertices(); for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df & tri = Triangles[triangleCount++]; tri.pointA = vtx[indices[index + 0]].Pos; tri.pointB = vtx[indices[index + 1]].Pos; tri.pointC = vtx[indices[index + 2]].Pos; } } break; case video::EVT_2TCOORDS: { video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buf->getVertices(); for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df & tri = Triangles[triangleCount++]; tri.pointA = vtx[indices[index + 0]].Pos; tri.pointB = vtx[indices[index + 1]].Pos; tri.pointC = vtx[indices[index + 2]].Pos; } } break; case video::EVT_TANGENTS: { video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buf->getVertices(); for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df & tri = Triangles[triangleCount++]; tri.pointA = vtx[indices[index + 0]].Pos; tri.pointB = vtx[indices[index + 1]].Pos; tri.pointC = vtx[indices[index + 2]].Pos; } } break; } } }
bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) { // write STL MESH header file->write("solid ",6); const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh)); file->write(name.c_str(),name.size()); file->write("\n\n",2); // write mesh buffers for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { IMeshBuffer* buffer = mesh->getMeshBuffer(i); if (buffer) { const u32 indexCount = buffer->getIndexCount(); for (u32 j=0; j<indexCount; j+=3) { writeFace(file, buffer->getPosition(buffer->getIndices()[j]), buffer->getPosition(buffer->getIndices()[j+1]), buffer->getPosition(buffer->getIndices()[j+2])); } file->write("\n",1); } } file->write("endsolid ",9); file->write(name.c_str(),name.size()); return true; }
//! renders the node. void CInstancedMeshSceneNode::render() { if (!IsVisible || !SceneManager->getActiveCamera()) return; if (!baseMesh || baseMesh->getMeshBuffer(0)->getVertexBuffer(1)->getVertexCount() == 0) return; IMeshBuffer* renderBuffer = baseMesh->getMeshBuffer(0); video::IVideoDriver* driver = SceneManager->getVideoDriver(); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setMaterial(readOnlyMaterial ? material : renderBuffer->getMaterial()); driver->drawMeshBuffer(renderBuffer); // for debug purposes only: if (DebugDataVisible) { video::SMaterial m; m.Lighting = false; driver->setMaterial(m); if (DebugDataVisible & scene::EDS_BBOX) driver->draw3DBox(box, video::SColor(255, 255, 255, 255)); if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) { const u32 size = instanceNodeArray.size(); for (u32 i = 0; i < size; ++i) { core::aabbox3df box = renderBuffer->getBoundingBox(); driver->setTransform(video::ETS_WORLD, instanceNodeArray[i]->getAbsoluteTransformation()); driver->draw3DBox(box, video::SColor(255, 255, 255, 255)); } } } }
IModelMesh* CResourceFactory::createModelMesh( const std::string& name, u32 sortcode, u32 vertexFormat, void* vertices, void* indices, u32 vertexCount, u32 vertexStride, u32 indiceCount, const math::SAxisAlignedBox& aabb, bool bit32Index, const std::vector<IModelMesh::SModelSubset>& subsets, E_MEMORY_USAGE usage) { IMeshBuffer* buffer = createMeshBuffer(usage, vertices, indices, vertexCount, indiceCount, vertexStride, bit32Index); if (!buffer) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str()); return nullptr; } if (subsets.size() < 1) { GF_PRINT_CONSOLE_INFO("FAIL:The mesh ('%s') create failed!. The subsets count must be greater than 1.\n", name.c_str()); return nullptr; } CModelMesh* mesh = new CModelMesh(name, sortcode, aabb, vertexFormat, subsets, buffer); if (!mesh) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str()); buffer->drop(); return nullptr; } return mesh; }
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; } }
void ISoftBody::updateSoftBody() { // Update the node position getWorldTransform(); node->setPosition(worldTransform.getTranslation()); node->setRotation(worldTransform.getRotationDegrees()); // Update the vertices u32 cMeshBuffer; IMeshBuffer *mb; IMesh* collMesh = node->getMesh(); s32 count = -1; for(cMeshBuffer=0; cMeshBuffer < 1; cMeshBuffer++) { mb = collMesh->getMeshBuffer(cMeshBuffer); updateMeshBuffer(mb, count); mb->recalculateBoundingBox(); } // Update the normals so they're not messed up by the soft body calculations node->getSceneManager()->getMeshManipulator()->recalculateNormals(collMesh, false, false); }
//! Sets a new mesh void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh) { if (!mesh) return; // won't set null mesh if (Mesh) Mesh->drop(); Mesh = mesh; // get materials and bounding box Box = Mesh->getBoundingBox(); IMesh* m = Mesh->getMesh(0,0); if (m) { Materials.clear(); video::SMaterial mat; for (u32 i=0; i<m->getMeshBufferCount(); ++i) { IMeshBuffer* mb = m->getMeshBuffer(i); if (mb) mat = mb->getMaterial(); Materials.push_back(mat); } } // get start and begin time setFrameLoop ( 0, Mesh->getFrameCount() ); // grab the mesh if (Mesh) Mesh->grab(); }
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; } }
void CTriangleSelector::updateFromMesh(const IMesh* mesh) const { if (!mesh) return; bool skinnnedMesh = mesh->getMeshType() == EAMT_SKINNED; u32 meshBuffers = mesh->getMeshBufferCount(); u32 triangleCount = 0; BoundingBox.reset(0.f, 0.f, 0.f); for (u32 i = 0; i < meshBuffers; ++i) { IMeshBuffer* buf = mesh->getMeshBuffer(i); u32 idxCnt = buf->getIndexCount(); const u16* indices = buf->getIndices(); if ( skinnnedMesh ) { const core::matrix4& bufferTransform = ((scene::SSkinMeshBuffer*)buf)->Transformation; for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df& tri = Triangles[triangleCount++]; bufferTransform.transformVect(tri.pointA, buf->getPosition(indices[index + 0])); bufferTransform.transformVect(tri.pointB, buf->getPosition(indices[index + 1])); bufferTransform.transformVect(tri.pointC, buf->getPosition(indices[index + 2])); BoundingBox.addInternalPoint(tri.pointA); BoundingBox.addInternalPoint(tri.pointB); BoundingBox.addInternalPoint(tri.pointC); } } else { for (u32 index = 0; index < idxCnt; index += 3) { core::triangle3df& tri = Triangles[triangleCount++]; tri.pointA = buf->getPosition(indices[index + 0]); tri.pointB = buf->getPosition(indices[index + 1]); tri.pointC = buf->getPosition(indices[index + 2]); BoundingBox.addInternalPoint(tri.pointA); BoundingBox.addInternalPoint(tri.pointB); BoundingBox.addInternalPoint(tri.pointC); } } } }
bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) { // write STL MESH header file->write("binary ",7); const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh)); const s32 sizeleft = 73-name.size(); // 80 byte header if (sizeleft<0) file->write(name.c_str(),73); else { char* buf = new char[80]; memset(buf, 0, 80); file->write(name.c_str(),name.size()); file->write(buf,sizeleft); delete [] buf; } u32 facenum = 0; for (u32 j=0; j<mesh->getMeshBufferCount(); ++j) facenum += mesh->getMeshBuffer(j)->getIndexCount()/3; file->write(&facenum,4); // write mesh buffers for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) { IMeshBuffer* buffer = mesh->getMeshBuffer(i); if (buffer) { const u32 indexCount = buffer->getIndexCount(); const u16 attributes = 0; for (u32 j=0; j<indexCount; j+=3) { const core::vector3df& v1 = buffer->getPosition(buffer->getIndices()[j]); const core::vector3df& v2 = buffer->getPosition(buffer->getIndices()[j+1]); const core::vector3df& v3 = buffer->getPosition(buffer->getIndices()[j+2]); const core::plane3df tmpplane(v1,v2,v3); file->write(&tmpplane.Normal, 12); file->write(&v1, 12); file->write(&v2, 12); file->write(&v3, 12); file->write(&attributes, 2); } } } return true; }
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); }