#include "VolumeStone.h" #include "windows.h" #include "PolyVoxCore/filters.h" VolumeStone::VolumeStone(Vector3DUint16 lowerCorner, Vector3DUint16 upperCorner, uint8_t uValue)//:volData(0) { volData = new SimpleVolume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 63, 31))); createCubeVolume(lowerCorner, upperCorner, uValue); mesh=new SurfaceMesh(); //mesh->clear();//new polyvox_shared_ptr>; //tmpMesh=new SurfaceMesh(); //mesh=new SurfaceMesh(); //mesh=new polyvox_shared_ptr>(); //graph=boost::shared_ptr(new Graph); oMO=NULL; surfaceExtractor=NULL; //oMO = vSM->createManualObject(); // create manual object //oMO->setDynamic(true); } VolumeStone::~VolumeStone(void) { } void VolumeStone::createCubeVolume(Vector3DUint16 lowerCorner, Vector3DUint16 upperCorner, uint8_t uValue) { //This three-level for loop iterates over every voxel between the specified corners for (int z = lowerCorner.getZ()+3; z <= upperCorner.getZ()-2; z++) { for (int y = lowerCorner.getY()+3; y <= upperCorner.getY()-2; y++) { for (int x = lowerCorner.getX()+3 ; x <= upperCorner.getX()-2; x++) { if (y<=60) { volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue,MaterialDensityPair44::getMaxDensity())); } else { volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue,MaterialDensityPair44::getMinDensity())); } //Our new density value //uint8_t uDensity = MaterialDensityPair44::getMaxDensity(); //Get the old voxel //MaterialDensityPair44 voxel = volData->getVoxelAt(x,y,z); //Modify the density //voxel.setDensity(uDensity); //Write the voxel value into the volume //volData->setVoxelAt(x, y, z, voxel); } } } } SimpleVolume* VolumeStone::updateVolData(float fRadius, uint8_t uValue,Ogre::Vector3 position) { //get the center of your knife!! Vector3DFloat v3dVolCenter(position.x,position.y,position.z); //This three-level for loop iterates over every voxel in the volume for (int z = 0; z < volData->getWidth(); z++) { for (int y = 0; y < volData->getHeight(); y++) { for (int x = 0; x < volData->getDepth(); x++) { if(volData->getVoxelAt(x,y,z).getDensity()!=MaterialDensityPair44::getMinDensity()) { //Store our current position as a vector... Vector3DFloat v3dCurrentPos(x,y,z); //And compute how far the current position is from the center of the volume float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length(); //If the current voxel is more than 'radius' units from the center //then we make it solid, otherwise we make it empty space. if(fDistToCenter >= fRadius) { volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue,MaterialDensityPair44::getMaxDensity())); //volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue, uValue > 0 ? MaterialDensityPair44::getMaxDensity() : MaterialDensityPair44::getMinDensity())); //volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue, MaterialDensityPair44::getMaxDensity())); } else volData->setVoxelAt(x,y,z, MaterialDensityPair44(uValue,MaterialDensityPair44::getMinDensity())); } } } } //smoothRegion(*volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 31, 31))); //smoothRegion(*volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 31, 31))); //smoothRegion(*volData, PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(31, 31, 31))); return volData; } Ogre::ManualObject* VolumeStone::updatePolyvox(Ogre::String materialName) { //createCubeVolume(lowerCorner,upperCorner,uValue); //Extract the surface //SurfaceMesh mesh; surfaceExtractor= new SurfaceExtractor(volData, volData->getEnclosingRegion(), mesh); //SurfaceExtractor surfaceExtractor(&volData, reg, &mesh); surfaceExtractor->execute(); ///////////////////////////////////////decimator //PolyVox::MeshDecimator de(mesh,tmpMesh); //de.execute(); //mesh=tmpMesh; return updateConvertPolyVoxMesh(materialName); //Pass the surface to the OpenGL window /////////////////////////////////////////////////////////////openGLWidget.setSurfaceMeshToRender(mesh); } Ogre::ManualObject* VolumeStone::initPolyvox(Ogre::String materialName,Ogre::SceneManager *sm) { //updateVolData(30, 4,Ogre::Vector3(61,61,61)); //createCubeVolume(lowerCorner,upperCorner,uValue); //Extract the surface //SurfaceMesh mesh; surfaceExtractor= new SurfaceExtractor(volData, volData->getEnclosingRegion(), mesh); surfaceExtractor->execute(); //PolyVox::surMeshDecimator meshDecimator; oMO = sm->createManualObject(); // create manual object oMO->setCastShadows(true); oMO->setDynamic(true); //return convertPolyVoxMesh(materialName); return updateConvertPolyVoxMesh(materialName); //Pass the surface to the OpenGL window /////////////////////////////////////////////////////////////openGLWidget.setSurfaceMeshToRender(mesh); } Ogre::ManualObject* VolumeStone::updateConvertPolyVoxMesh(Ogre::String materialName) { // Create Mesh and SceneNode //ManualObject* ogreMesh; // create something to draw the PolyVox stuff to //ogreMesh = mSceneMgr->createManualObject("PolyVox Mesh"); // YES we do intend to change the mesh later -.- //ogreMesh->setDynamic(true); oMO->begin("materialName", Ogre::RenderOperation::OT_TRIANGLE_LIST); { // prepare the buffers const std::vector& vecIndices = mesh->getIndices(); const std::vector& vecVertices = mesh->getVertices(); //unsigned int uLodLevel = 0; //int beginIndex = mesh->m_vecLodRecords[uLodLevel].beginIndex; //int endIndex = mesh->m_vecLodRecords[uLodLevel].endIndex; oMO->estimateVertexCount(vecVertices.size()); oMO->estimateIndexCount(vecIndices.size()); //uint32_t numOgreIndices = mesh->getNoOfIndices(); //uint32_t numOgreVertices = mesh->getNoOfVertices(); //for(int index = 0 ; index < numOgreIndices ; index++) //for (int index = beginIndex; index < endIndex; ++index) for(uint32_t i = 0; i < vecVertices.size(); i++) { const PolyVox::PositionMaterialNormal& vertex = vecVertices.at(i); //const MaterialAlpha& ma = vertex_extra_data.at(i); PolyVox::Vector3DFloat vertex_pos = vertex.getPosition() /*+static_cast(mesh->m_Region.getLowerCorner())*/; //oMO->position(vertex_pos.getX(),vertex_pos.getY(),vertex_pos.getZ()); const PolyVox::Vector3DFloat v3dFinalVertexPos = vertex_pos + static_cast(mesh->m_Region.getLowerCorner()); oMO->position(v3dFinalVertexPos.getX(), v3dFinalVertexPos.getY(), v3dFinalVertexPos.getZ()); oMO->normal(vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ()); oMO->index((Ogre::uint32)(vecIndices[i])); //oMO->index(i); /* const PolyVox::PositionMaterialNormal& vertex = vecVertices[vecIndices[index]]; const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition(); const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal(); //const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength); const PolyVox::Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast(mesh->m_Region.getLowerCorner()); oMO->index((Ogre::uint32)(index)); oMO->position(v3dFinalVertexPos.getX(), v3dFinalVertexPos.getY(), v3dFinalVertexPos.getZ()); oMO->normal(v3dVertexNormal.getX(), v3dVertexNormal.getY(), v3dVertexNormal.getZ()); //uint8_t mat = vertex.getMaterial() + 0.5; //uint8_t red = mat & 0xF0; ///uint8_t green = mat & 0x03; //uint8_t blue = mat & 0x0C; //ogreMesh->colour(red*2, green*4, blue*4);// just some random colors, I'm too lazy for hsv*/ } /* for (uint32_t i=0;iindex((Ogre::uint32)(vecIndices[i])); } */ } oMO->end(); return oMO; } //Ogre::ManualObject* VolumeStone::updateConvertPolyVoxMesh(Ogre::String materialName) //{ //Ogre::ManualObject* ogreManualObject = NULL; //oMO->beginUpdate(0); //oMO->begin(materialName, Ogre::RenderOperation::OT_TRIANGLE_LIST); //if(mesh && mesh->getNoOfVertices() > 0 && mesh->getNoOfIndices() > 0) // make sure mesh is allocated and valid first //{ /* const std::vector& indexVector = mesh->getIndices(); // get a vector of all indices const std::vector& vertexVector = mesh->getVertices(); // get a vector of all vertices //oMO = sm->createManualObject(); // create manual object //oMO->setDynamic(true); uint32_t numOgreIndices = mesh->getNoOfIndices(); uint32_t numOgreVertices = mesh->getNoOfVertices(); oMO->estimateIndexCount(numOgreIndices); // set index/vertex counts before starting to speed up allocations oMO->estimateVertexCount(numOgreVertices); oMO->begin(materialName, Ogre::RenderOperation::OT_TRIANGLE_LIST); // start adding triangles //oMO->beginUpdate(0); // start adding triangles PolyVox::Vector3DFloat positionTempVar; // iterate through vertices for(int v = 0 ; v < numOgreVertices ; v++) { positionTempVar = vertexVector[v].getPosition(); // get position vector from vertex list oMO->position((Ogre::Real)(positionTempVar.getX()), (Ogre::Real)(positionTempVar.getY()), (Ogre::Real)(positionTempVar.getZ())); // add a new vertex to ogre manualobject } // iterate through indices for(int i = 0 ; i < numOgreIndices ; i++) { oMO->index((Ogre::uint32)(indexVector[i])); // set indices in same order as polyvox mesh (if using DirectX render system, may differ for OpenGL) } oMO->end(); // stop adding triangles */ /* oMO->begin(materialName, Ogre::RenderOperation::OT_TRIANGLE_LIST); const std::vector& vecVertices = mesh->getVertices(); const std::vector& vecIndices = mesh->getIndices(); unsigned int uLodLevel = 0; int beginIndex = mesh->m_vecLodRecords[uLodLevel].beginIndex; int endIndex = mesh->m_vecLodRecords[uLodLevel].endIndex; for(int index = beginIndex; index < endIndex; ++index) { const PolyVox::PositionMaterialNormal& vertex = vecVertices[vecIndices[index]]; const PolyVox::Vector3DFloat& v3dVertexPos = vertex.getPosition(); const PolyVox::Vector3DFloat& v3dVertexNormal = vertex.getNormal(); //const Vector3DFloat v3dRegionOffset(uRegionX * g_uRegionSideLength, uRegionY * g_uRegionSideLength, uRegionZ * g_uRegionSideLength); const PolyVox::Vector3DFloat v3dFinalVertexPos = v3dVertexPos + static_cast(mesh->m_Region.getLowerCorner()); oMO->position(v3dFinalVertexPos.getX(), v3dFinalVertexPos.getY(), v3dFinalVertexPos.getZ()); oMO->normal(v3dVertexNormal.getX(), v3dVertexNormal.getY(), v3dVertexNormal.getZ()); } */ /* const std::vector& indexVector = mesh->getIndices(); // get a vector of all indices const std::vector& vertexVector = mesh->getVertices(); // get a vector of all vertices //oMO = sm->createManualObject(); // create manual object //oMO->setDynamic(true); uint32_t numOgreIndices = mesh->getNoOfIndices(); uint32_t numOgreVertices = mesh->getNoOfVertices(); oMO->estimateIndexCount(numOgreIndices); // set index/vertex counts before starting to speed up allocations oMO->estimateVertexCount(numOgreVertices); oMO->begin(materialName, Ogre::RenderOperation::OT_TRIANGLE_LIST); // start adding triangles //oMO->beginUpdate(0); // start adding triangles PolyVox::Vector3DFloat positionTempVar; // iterate through vertices for(int v = 0 ; v < numOgreVertices ; v++) { positionTempVar = vertexVector[v].getPosition(); // get position vector from vertex list oMO->position((Ogre::Real)(positionTempVar.getX()), (Ogre::Real)(positionTempVar.getY()), (Ogre::Real)(positionTempVar.getZ())); // add a new vertex to ogre manualobject } // iterate through indices for(int i = 0 ; i < numOgreIndices ; i++) { oMO->index((Ogre::uint32)(indexVector[i])); // set indices in same order as polyvox mesh (if using DirectX render system, may differ for OpenGL) }*/ // oMO->end(); // stop adding triangles // } // return oMO; //} /* Ogre::ManualObject* VolumeStone::convertPolyVoxMesh(Ogre::String materialName) { //Ogre::ManualObject* ogreManualObject = NULL; if(mesh && mesh->getNoOfVertices() > 0 && mesh->getNoOfIndices() > 0) // make sure mesh is allocated and valid first { const std::vector& indexVector = mesh->getIndices(); // get a vector of all indices const std::vector& vertexVector = mesh->getVertices(); // get a vector of all vertices uint32_t numOgreIndices = mesh->getNoOfIndices(); uint32_t numOgreVertices = mesh->getNoOfVertices(); oMO->estimateIndexCount(numOgreIndices); // set index/vertex counts before starting to speed up allocations oMO->estimateVertexCount(numOgreVertices); oMO->begin(materialName, Ogre::RenderOperation::OT_TRIANGLE_LIST); // start adding triangles PolyVox::Vector3DFloat positionTempVar; // iterate through vertices for(int v = 0 ; v < numOgreVertices ; v++) { positionTempVar = vertexVector[v].getPosition(); // get position vector from vertex list oMO->position((Ogre::Real)(positionTempVar.getX()), (Ogre::Real)(positionTempVar.getY()), (Ogre::Real)(positionTempVar.getZ())); // add a new vertex to ogre manualobject } // iterate through indices for(int i = 0 ; i < numOgreIndices ; i++) { oMO->index((Ogre::uint32)(indexVector[i])); // set indices in same order as polyvox mesh (if using DirectX render system, may differ for OpenGL) } oMO->end(); // stop adding triangles } return oMO; }*/