| Volumes Of Fun http://www.volumesoffun.com/phpBB3/ |
|
| Realtime Ogre 1.8 Terrain Component manipulation http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=312 |
Page 9 of 13 |
| Author: | drwbns [ Fri Feb 10, 2012 1:48 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
Ok, thanks for the useful information David. I still have a crash on a very small region in Release mode - still a buffer overrun. I'm still hesitant to add any code until I figure out what is the root cause of it. I've only taken away code in hopes of it disappearing, but I don't have much code left to delete in my frame render function. It looks like so - Code: bool WorldCraft::frameRenderingQueued(const Ogre::FrameEvent& evt) { if(mKeyDevices.mWindow->isClosed()) return false; if(mShutDown) return false; //Need to capture/update each device mKeyDevices.mKeyboard->capture(); mKeyDevices.mMouse->capture(); CEGUI::MouseCursor::getSingleton().setPosition(CEGUI::Point(mCamera->getViewport()->getActualWidth() / 2, mCamera->getViewport()->getActualHeight() / 2)); if(!processUnbufferedInput(evt)) return false; //The next 3 paragraphs display FPS info to screen float last; float avg; float best; float worst; mKeyDevices.mWindow->getStatistics(last,avg,best,worst); char tmp[32]; sprintf(tmp, "FPS: %f", last); sprintf(tmp, "Avg FPS: %f", avg); // Update SkyX mSkyX->update(evt.timeSinceLastFrame); OIS::MouseState ms = mKeyDevices.mMouse->getMouseState(); ms.Y.abs = mCamera->getViewport()->getActualHeight() / 2; ms.X.abs = mCamera->getViewport()->getActualWidth() / 2; Ogre::Ray ray = mCamera->getCameraToViewportRay((float)ms.X.abs / (float)ms.width, (float)ms.Y.abs / (float)ms.height); Ogre::Vector3 pos = ray.getOrigin(); Ogre::Vector3 dir = ray.getDirection(); // Find the voxel we are looking at. PolyVox::Vector3DFloat start(pos.x,pos.y,pos.z); PolyVox::Vector3DFloat direction(dir.x, dir.y, dir.z); direction *= 1000.0f; //Casts ray of length 1000 PolyVox::RaycastResult raycastResult; PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8> raycast(&volData, start, direction, raycastResult); raycast.execute(); if(raycastResult.foundIntersection) { // Set marker node position mKeyDevices.mSceneMgr->getSceneNode("mEditNode")->setPosition(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ()); } if (ms.buttonDown(OIS::MB_Left)){ if(raycastResult.foundIntersection) { volData.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity); } } return true; } UPDATE: looks like I found the cause of the overrun, as it doesn't seem to crash after removing this piece from the framerender function ( ker's code) - Code: PolyVox::Vector3DFloat sig( (dir.x < 0)?(-1.0f):((dir.x > 0)?(1.0f):(0)), (dir.y < 0)?(-1.0f):((dir.y > 0)?(1.0f):(0)), (dir.z < 0)?(-1.0f):((dir.z > 0)?(1.0f):(0)) ); My function in full looked like so - Code: bool WorldCraft::frameRenderingQueued(const Ogre::FrameEvent& evt)
{ if(mKeyDevices.mWindow->isClosed()) return false; if(mShutDown) return false; //Need to capture/update each device mKeyDevices.mKeyboard->capture(); mKeyDevices.mMouse->capture(); CEGUI::MouseCursor::getSingleton().setPosition(CEGUI::Point(mCamera->getViewport()->getActualWidth() / 2, mCamera->getViewport()->getActualHeight() / 2)); if(!processUnbufferedInput(evt)) return false; //The next 3 paragraphs display FPS info to screen float last; float avg; float best; float worst; mKeyDevices.mWindow->getStatistics(last,avg,best,worst); char tmp[32]; sprintf(tmp, "FPS: %f", last); //mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSinfo")->setText(tmp); sprintf(tmp, "Avg FPS: %f", avg); //mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSAvg")->setText(tmp); // Update SkyX mSkyX->update(evt.timeSinceLastFrame); OIS::MouseState ms = mKeyDevices.mMouse->getMouseState(); ms.Y.abs = mCamera->getViewport()->getActualHeight() / 2; ms.X.abs = mCamera->getViewport()->getActualWidth() / 2; Ogre::Ray ray = mCamera->getCameraToViewportRay((float)ms.X.abs / (float)ms.width, (float)ms.Y.abs / (float)ms.height); Ogre::Vector3 pos = ray.getOrigin(); Ogre::Vector3 dir = ray.getDirection(); // Find the voxel we are looking at. PolyVox::Vector3DFloat start(pos.x,pos.y,pos.z); PolyVox::Vector3DFloat direction(dir.x, dir.y, dir.z); /* PolyVox::Vector3DFloat sig( (dir.x < 0)?(-1.0f):((dir.x > 0)?(1.0f):(0)), (dir.y < 0)?(-1.0f):((dir.y > 0)?(1.0f):(0)), (dir.z < 0)?(-1.0f):((dir.z > 0)?(1.0f):(0)) ); */ direction *= 1000.0f; //Casts ray of length 1000 PolyVox::RaycastResult raycastResult; PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8> raycast(&volData, start, direction, raycastResult); raycast.execute(); /* PolyVox::Vector3DFloat r = (PolyVox::Vector3DFloat(raycastResult.previousVoxel) + sig*float(0.5) - start)/direction; // grabbed from my source, it shows the point the mouse points at inside the world // and its normal PolyVox::Vector3DFloat m_vecMousePointPosition; PolyVox::Vector3DFloat m_vecMousePointNormal; if(r.getX() < r.getY() && r.getX() < r.getZ()) { m_vecMousePointPosition = start + direction*r.getX(); m_vecMousePointNormal.setX(-sig.getX()); m_vecMousePointNormal.setY(0); m_vecMousePointNormal.setZ(0); } else if(r.getY() < r.getZ()) { m_vecMousePointPosition = start + direction*r.getY(); m_vecMousePointNormal.setX(0); m_vecMousePointNormal.setY(-sig.getY()); m_vecMousePointNormal.setZ(0); } else { m_vecMousePointPosition = start + direction*r.getZ(); m_vecMousePointNormal.setX(0); m_vecMousePointNormal.setY(0); m_vecMousePointNormal.setZ(-sig.getZ()); } */ // Find the voxel we are looking at. //PolyVox::Vector3DFloat start(100,100,100); //PolyVox::Vector3DFloat direction(0, -1, 0); //direction.normalise(); if(raycastResult.foundIntersection) { // Update stats /* mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSinfo")->setText(Ogre::StringConverter::toString(Vector3(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ())).c_str()); sprintf(tmp, "Previous: %f",Ogre::StringConverter::toString(Vector3(raycastResult.previousVoxel.getX(), raycastResult.previousVoxel.getY(), raycastResult.previousVoxel.getZ()))); mKeyDevices.guiRoot->getChild("Root/DebugWindow")->getChild("Root/DebugWindow/FPSAvg")->setText(tmp); */ // Set marker node position mKeyDevices.mSceneMgr->getSceneNode("mEditNode")->setPosition(raycastResult.intersectionVoxel.getX(), raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ()); } if (ms.buttonDown(OIS::MB_Left)){ if(raycastResult.foundIntersection) { volData.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity); } } return true; } |
|
| Author: | David Williams [ Fri Feb 10, 2012 2:06 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
This doesn't quite make sense to me... you've shown the declaration of 'sig' is now commented out but you are still using the variable 'sig' later on in the code. That shouldn't even compile... More generally, I think you should not use ker's code. I believe it does work, but you're probably not using it correctly and I don't think it is applicable to your scenario anyway. Lastly, it seems a bit strange to me that you are performing tasks like raycasting in the 'frameRenderingQueued' function. I'm not really that knowledgeable about Ogre but I would expect to see this in the game loop somewhere and to have only rendering related code in 'frameRenderingQueued'. Not sure if it's actually a problem, but some reorganisation but be useful. |
|
| Author: | drwbns [ Fri Feb 10, 2012 2:42 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
David Williams wrote: This doesn't quite make sense to me... you've shown the declaration of 'sig' is now commented out but you are still using the variable 'sig' later on in the code. That shouldn't even compile... All sig uses are commented out, I think you may have trouble reading where the comments are e.g. (/*, */) David Williams wrote: More generally, I think you should not use ker's code. I believe it does work, but you're probably not using it correctly and I don't think it is applicable to your scenario anyway. You're right, I don't think I need it either. David Williams wrote: Lastly, it seems a bit strange to me that you are performing tasks like raycasting in the 'frameRenderingQueued' function. I'm not really that knowledgeable about Ogre but I would expect to see this in the game loop somewhere and to have only rendering related code in 'frameRenderingQueued'. Not sure if it's actually a problem, but some reorganisation but be useful. AFAIK that's where the main loop is and where the work should be done. I've never really seen real-time editing done anywhere else. |
|
| Author: | David Williams [ Fri Feb 10, 2012 2:52 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
drwbns wrote: All sig uses are commented out, I think you may have trouble reading where the comments are e.g. (/*, */) Sorry, you are right, I couldn't read the comments without syntax highlighting. drwbns wrote: AFAIK that's where the main loop is and where the work should be done. I've never really seen real-time editing done anywhere else. Ok, maybe it's fine then. I don't really know enough about Ogre to be sure about this. |
|
| Author: | drwbns [ Fri Feb 10, 2012 3:47 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I made a function that creates or redraws the voxel region. The problem is that it takes about 2 seconds to complete an update on a 513 x 513 x 256 volume with basically all of the time being dedicated to surface extraction. I still need a quicker solution for real time updating. This can update in real time on a very small volume. I thought I'd post it just in case someone wants a redraw method. Sorry for the commented code I've been using for testing... Code: void WorldCraft::PolyvoxMeshtoManual(void)
{ // ************ start mesh build code // Make a surfaceMesh from the voxelData SurfaceMesh<PositionMaterialNormal> mesh; SurfaceMesh<PositionMaterialNormal> mesh2; // Reduced mesh - use for non-smooth mesh /* Region reducedRegion = volData.getEnclosingRegion(); reducedRegion.shiftLowerCorner(Vector3DInt32(2,2,2)); reducedRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); PolyVox::CubicSurfaceExtractorWithNormals<SimpleVolume, Density8> surf(&volData, reducedRegion, &mesh); // Smooth using a lowpassfilter Region fullRegion = volData.getEnclosingRegion(); //fullRegion.shiftLowerCorner(Vector3DInt32(2,2,2)); //fullRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); SimpleVolume<Density8> resultVolume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(myTerrainHM.getWidth(),256,myTerrainHM.getHeight()))); Region fullRegion2 = resultVolume.getEnclosingRegion(); fullRegion2.shiftLowerCorner(Vector3DInt32(2,2,2)); fullRegion2.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); LowPassFilter<SimpleVolume, SimpleVolume, Density8> pass1(&volData, fullRegion2, &resultVolume, fullRegion2, 5); pass1.execute(); */ // Extract the surface //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&volData, volData.getEnclosingRegion(), &mesh); // Use for semi-smooth surface PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(&volData, volData.getEnclosingRegion(), &mesh); // Use if not smoothing surf.execute(); //Optional in release mode - simplify (decimate) the mesh //PolyVox::MeshDecimator<PolyVox::PositionMaterialNormal> decim(&mesh, &mesh2); //decim.execute(); // Change mesh to mesh2 if using decimation const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices(); const std::vector<uint32_t>& vecIndices = mesh.getIndices(); // create something to draw the PolyVox stuff to /* if(ogreMesh != NULL) { ogreNode->detachObject(ogreMesh); mKeyDevices.mSceneMgr->destroyManualObject(ogreMesh); ogreMesh = NULL; } */ if(ogreMesh == NULL) { ogreMesh = mKeyDevices.mSceneMgr->createManualObject("PolyVox Mesh"); // YES we do intend to change the mesh later -.- ogreMesh->setDynamic(true); ogreMesh->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST); } else ogreMesh->beginUpdate(0); if(ogreMesh != NULL) { /* if ( ogreNode != NULL) { mKeyDevices.mSceneMgr->destroySceneNode(ogreNode); ogreNode = NULL; } */ if (ogreNode == NULL) { ogreNode = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode("testnode1", Ogre::Vector3(0, 0, 0)); } // Begin writing to manualObject unsigned int uLodLevel = 0; for(int index = 0; index < vecIndices.size(); 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<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner()); ogreMesh->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ()); ogreMesh->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 } // end writing ogreMesh->end(); //atach object to node if (mMeshAttached == false) ogreNode->attachObject(ogreMesh); mMeshAttached = true; } } |
|
| Author: | drwbns [ Tue Feb 14, 2012 7:47 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I changed my function to take a structure, but it's crashing during the same Raycast that worked fine before and I'm not really sure why. The crash happens in simpleVolumeSampler.inl in this block of code with an Access Violation. Raycast is like so - Code: PolyVox::RaycastResult raycastResult; PolyVox::Raycast<PolyVox::SimpleVolume, PolyVox::Density8> raycast(&pMesh.volume, start, direction, raycastResult); raycast.execute(); crash stops here- Code: template <typename VoxelType> VoxelType SimpleVolume<VoxelType>::Sampler::getVoxel(void) const { return *mCurrentVoxel; } my custom stucture to hold volume, node data - Code: struct Polymesh { PolyVox::SimpleVolume<Density8> volume; Ogre::SceneNode * node; Ogre::ManualObject * meshOBJ; Vector3 position; Polymesh():volume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(100,256,100))), node(NULL), meshOBJ(NULL){} }; function that takes Polymesh structure and renders a mesh from it - Code: void WorldCraft::PolyvoxMeshtoManual(Polymesh pMesh)
{ // ************ start mesh build code // Make a surfaceMesh from the voxelData SurfaceMesh<PositionMaterialNormal> mesh; SurfaceMesh<PositionMaterialNormal> mesh2; // Reduced mesh - use for non-smooth mesh /* Region reducedRegion = volData.getEnclosingRegion(); reducedRegion.shiftLowerCorner(Vector3DInt32(2,2,2)); reducedRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); PolyVox::CubicSurfaceExtractorWithNormals<SimpleVolume, Density8> surf(&volData, reducedRegion, &mesh); // Smooth using a lowpassfilter Region fullRegion = volData.getEnclosingRegion(); //fullRegion.shiftLowerCorner(Vector3DInt32(2,2,2)); //fullRegion.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); SimpleVolume<Density8> resultVolume(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(myTerrainHM.getWidth(),256,myTerrainHM.getHeight()))); Region fullRegion2 = resultVolume.getEnclosingRegion(); fullRegion2.shiftLowerCorner(Vector3DInt32(2,2,2)); fullRegion2.shiftUpperCorner(Vector3DInt32(-2,-2,-2)); LowPassFilter<SimpleVolume, SimpleVolume, Density8> pass1(&volData, fullRegion2, &resultVolume, fullRegion2, 5); pass1.execute(); */ // Extract the surface //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&pMesh.volume, pMesh.volume.getEnclosingRegion(), &mesh); // Use for semi-smooth surface //PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(pMesh.volume, pMesh.volume->getEnclosingRegion(), &mesh); // Use if not smoothing surf.execute(); //Optional in release mode - simplify (decimate) the mesh //PolyVox::MeshDecimator<PolyVox::PositionMaterialNormal> decim(&mesh, &mesh2); //decim.execute(); // Change mesh to mesh2 if using decimation const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices(); const std::vector<uint32_t>& vecIndices = mesh.getIndices(); // create something to draw the PolyVox stuff to /* if(ogreMesh != NULL) { ogreNode->detachObject(ogreMesh); mKeyDevices.mSceneMgr->destroyManualObject(ogreMesh); ogreMesh = NULL; } */ if(pMesh.meshOBJ == NULL) { pMesh.meshOBJ = mKeyDevices.mSceneMgr->createManualObject(); // YES we do intend to change the mesh later -.- pMesh.meshOBJ->setDynamic(true); pMesh.meshOBJ->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST); } else pMesh.meshOBJ->beginUpdate(0); if(pMesh.meshOBJ != NULL) { /* if ( ogreNode != NULL) { mKeyDevices.mSceneMgr->destroySceneNode(ogreNode); ogreNode = NULL; } */ if (pMesh.node == NULL) { pMesh.node = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode(pMesh.position); } // Begin writing to manualObject unsigned int uLodLevel = 0; for(int index = 0; index < vecIndices.size(); 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<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner()); pMesh.meshOBJ->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ()); pMesh.meshOBJ->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; pMesh.meshOBJ->colour(red*2, green*4, blue*4);// just some random colors, I'm too lazy for hsv } // end writing pMesh.meshOBJ->end(); //atach object to node pMesh.node->attachObject(pMesh.meshOBJ); } } |
|
| Author: | David Williams [ Wed Feb 15, 2012 9:29 am ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I'm not sure if it is the problem, but it appears you are creating a seperate volume for each mesh. You shouldn't do this - instead you should have a single volume for your whole world. You should then create multiple meshes from this single volume, where each mesh corresponds to a different part of the volume. You can do this by passing a Region to the surface extractor, and so each mesh will be generated from the same volume but using a different region. |
|
| Author: | drwbns [ Sat Feb 18, 2012 7:22 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I've switched everything to use a single volume and I'm now splitting the volume into 64 x 64 x 64 regions and extracting a mesh for each region, then attaching the mesh to a seperate node but I'm having trouble raycasting to the correct node. I seem to only be able to get 1 node when using the following code - Code: if (ms.buttonDown(OIS::MB_Left)){ if(raycastResult.foundIntersection) { volume.setVoxelAt(raycastResult.intersectionVoxel,VoxelTypeTraits<Density8>::MinDensity); float distance, oldDistance = 0.0; Polymesh p; for( std::vector<Polymesh>::iterator i = polyMeshes.begin(); i != polyMeshes.end(); i ++){ if((*i).meshOBJ->getBoundingBox().contains(Vector3( raycastResult.intersectionVoxel.getX() ,raycastResult.intersectionVoxel.getY(), raycastResult.intersectionVoxel.getZ()))) p = (*i); } PolyvoxMeshtoManual(p); //PolyvoxMeshtoManual(reg); } } my Polymesh struct looks almost the same as before - Code: struct Polymesh { Region region; SceneNode * node; ManualObject * meshOBJ; Vector3 position; bool mMeshAttached; Polymesh():node(NULL), meshOBJ(NULL), position(Vector3(0,0,0)), mMeshAttached(false){} }; and my mesh rendering function - Code: void WorldCraft::PolyvoxMeshtoManual(Polymesh &p)
{ // ************ start mesh build code // Make a surfaceMesh from the voxelData SurfaceMesh<PositionMaterialNormal> mesh; SurfaceMesh<PositionMaterialNormal> mesh2; // Extract the surface //PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&resultVolume, fullRegion2, &mesh); // Use if smoothing PolyVox::SurfaceExtractor<SimpleVolume, Density8> surf(&volume, p.region, &mesh); // Use for semi-smooth surface //PolyVox::CubicSurfaceExtractorWithNormals <SimpleVolume, Density8> surf(pMesh.volume, pMesh.volume->getEnclosingRegion(), &mesh); // Use if not smoothing surf.execute(); // Change mesh to mesh2 if using decimation const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices(); const std::vector<uint32_t>& vecIndices = mesh.getIndices(); if(p.meshOBJ == NULL) { p.meshOBJ = mKeyDevices.mSceneMgr->createManualObject(); // YES we do intend to change the mesh later -.- p.meshOBJ->setDynamic(true); p.meshOBJ->estimateIndexCount(17000); p.meshOBJ->estimateVertexCount(17000); p.meshOBJ->begin("Worldcraft/Greengrass", Ogre::RenderOperation::OT_TRIANGLE_LIST); } else p.meshOBJ->beginUpdate(0); if(p.meshOBJ != NULL) { if (p.node == NULL) { p.node = mKeyDevices.mSceneMgr->getRootSceneNode()->createChildSceneNode(p.position); } // Begin writing to manualObject unsigned int uLodLevel = 0; for(int index = 0; index < vecIndices.size(); 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<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner()); p.meshOBJ->position(v3dVertexPos.getX(), v3dVertexPos.getY(), v3dVertexPos.getZ()); p.meshOBJ->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; p.meshOBJ->colour(red*2, green*4, blue*4); } // end writing p.meshOBJ->end(); if (p.mMeshAttached == false){ p.node->attachObject(p.meshOBJ); p.mMeshAttached = true; p.node->showBoundingBox(true); } else { if (p.node->getShowBoundingBox() == true) p.node->showBoundingBox(false); else p.node->showBoundingBox(true); } } } |
|
| Author: | David Williams [ Sun Feb 19, 2012 8:56 am ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I'm not certain, but you may find that all your nodes have the same bounding box (e.g. (0,0,0) to (64, 64, 64)) and that you also need to take into account the position of the node (which might be something like (64, 128, 128)) in order to get the real bounding box. E.g. the Ogre bounding box may be local to that node and you may need to transform it into world space. However, you don't actually need to use the bounding boxes to determine which node a voxel is in. Thinking in one dimension, let's say we have a range from 0 to 255 which is broken up unto chunks of 64 (0-63, 64-127, 128-191, 192-255). If we have position 150, we do not need to check each of the ranges to see if it within them. Instead we just use integer division: 150 / 64 = 2 tells us it is in the second range (where we consider them to be numbered starting from zero). Integer division and modulus operation are very useful in voxel worlds. |
|
| Author: | drwbns [ Sun Feb 19, 2012 6:33 pm ] |
| Post subject: | Re: Realtime Ogre 1.8 Terrain Component manipulation |
I'm not really sure I understand your method of finding a node based off division. Sure that gets a number, but how does a "range" determine which node a voxel is in? |
|
| Page 9 of 13 | All times are UTC |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|