#include "OgreCubeMapRenderingRun.h" #include "OgreIlluminationManager.h" OgreCubeMapRenderingRun::OgreCubeMapRenderingRun(OgreSharedRuns* sharedRuns, String name, unsigned long startFrame, unsigned long updateInterval, unsigned int resolution, bool useDistCalc, bool useFaceAngleCalc, float distTolerance, float angleTolerance, bool updateAllFace, bool renderSelf, bool renderEnvironment, String selfMaterial, String environmentMaterial, bool getMinMax, RenderingRunType cubemapRunType) :CubeMapRenderingRun(startFrame, updateInterval, resolution, useDistCalc, useFaceAngleCalc, distTolerance, angleTolerance, updateAllFace, renderSelf, renderEnvironment) , OgreRenderingRun(startFrame, updateInterval) , RenderingRun(startFrame, updateInterval) { this->getMinMax = getMinMax; this->cubemapRunType = cubemapRunType; this->sharedRuns = sharedRuns; this->name = name; this->selfMaterial = selfMaterial; this->environmentMaterial = environmentMaterial; if(environmentMaterial == "") useEnvMaterial = false; else useEnvMaterial = true; if(selfMaterial == "") useSelfMaterial = false; else useSelfMaterial = true; createCubeMap(); } void OgreCubeMapRenderingRun::createCubeMap() { ColourValue clearColor = ColourValue::Black; clearColor.a = 0.0; cubemapTexture = createCubeRenderTexture(name, sharedRuns->getRootPosition(), resolution, PF_FLOAT16_RGBA, //PF_R8G8B8A8, 0, clearColor); } void OgreCubeMapRenderingRun::updateCubeFace(int facenum) { OgreSharedRuns* root = (OgreSharedRuns*) sharedRuns->getRoot(cubemapRunType); SceneManager* sm = Ogre::Root::getSingleton()._getCurrentSceneManager(); RenderQueue* rq = sm->getRenderQueue(); RenderTarget* rt = cubemapTexture->getBuffer(facenum, 0).getPointer()->getRenderTarget(); Camera* cam = rt->getViewport(0)->getCamera(); Vector3 center = sharedRuns->getRootPosition(cubemapRunType); cam->setPosition(center); bool renderAllwithOwnColor = false; if(renderSelf && renderEnvironment && !useSelfMaterial && !useEnvMaterial) renderAllwithOwnColor = true; if(!renderAllwithOwnColor) { root->hide(); if(renderEnvironment) { if(useEnvMaterial) { setMaterialForVisibles(environmentMaterial, cam); //sm->_queueSkiesForRendering(cam); } else { //sm->_findVisibleObjectsOC(cam, rt->getViewport(0), false, false, false); sm->_findVisibleObjects(cam, false); sm->_queueSkiesForRendering(cam); sm->setFindVisibleObjects(false); } } else { rq->clear(); sm->setFindVisibleObjects(false); } if(renderSelf) { root->restoreVisibility(); if(useSelfMaterial) root->setMaterial(selfMaterial); root->addRenderablesToQueue(rq); } } rt->update(); //rt->writeContentsToFile( "cubeLayer" + StringConverter::toString(cubemapRunType)+ "face" + StringConverter::toString(facenum) + ".dds"); if(!renderAllwithOwnColor) { if(renderEnvironment && useEnvMaterial) restoreMaterials(); else sm->setFindVisibleObjects(true); if(!renderSelf) root->restoreVisibility(); else if(useSelfMaterial) root->restoreMaterial(); } if(facenum == 5 && getMinMax) { getCubeMapMinMax(); this->sharedRuns->runUpdated(cubemapRunType, this); } } void OgreCubeMapRenderingRun::getCubeMapMinMax() { unsigned int buffersize = resolution * resolution * 4; float* floatbuffer = new float[buffersize]; PixelBox lockBox(resolution, resolution, 1, PF_FLOAT32_RGBA, floatbuffer); float minX = 0; float minY = 0; float minZ = 0; float minW = 0; float maxX = 0; float maxY = 0; float maxZ = 0; float maxW = 0; bool first = true; for(int iFace = 0; iFace <6 ; iFace++) { this->cubemapTexture->getBuffer(iFace,0)->blitToMemory(lockBox); for(unsigned int i = 0; i < buffersize; i+= 4) { float x = floatbuffer[i]; float y = floatbuffer[i + 1]; float z = floatbuffer[i + 2]; float w = floatbuffer[i + 3]; if(first && w != 0) { minX = x; minY = y; minZ = z; minW = w; maxX = x; maxY = y; maxZ = z; maxW = w; first = false; } else if( /*(x * x + y * y + z * z + w * w) != 0*/ w != 0) { if(x < minX)minX = x; if(y < minY)minY = y; if(z < minZ)minZ = z; if(w < minW)minW = w; if(x > maxX)maxX = x; if(y > maxY)maxY = y; if(z > maxZ)maxZ = z; if(w > maxW)maxW = w; } } } min.x = minX; min.y = minY; min.z = minZ; min.w = minW; max.x = maxX; max.y = maxY; max.z = maxZ; max.w = maxW; delete[] floatbuffer; } bool OgreCubeMapRenderingRun::faceNeedsUpdate(int facenum) { if(useDistCalc || useFaceAngleCalc) { float chance1 = 1.0; float chance2 = 1.0; Camera* mainCamera = OgreIlluminationManager::getSingleton().getMainCamera(); if(useDistCalc) { Vector3 cubemapPosition = sharedRuns->getRootPosition(cubemapRunType); float objradius = sharedRuns->getRootBoundingSphere(cubemapRunType).getRadius(); float fov = mainCamera->getFOVy().valueRadians() / 2.0; float dist = (cubemapPosition - mainCamera->getPosition()).length(); float vangle = Math::ASin( objradius / dist).valueRadians(); float angleratio = vangle / fov; chance1 = Math::Pow(angleratio, 1.0 / distTolerance); } if(useFaceAngleCalc) { Vector3 faceDir = getCubeMapFaceDirection(facenum); Vector3 cameraDir = mainCamera->getDirection(); float angle = faceDir.dotProduct(-1 * cameraDir); float facingforward = (angle + 1) / 2.0; chance2 = Math::Pow(facingforward, 1.0 / angleTolerance); } float dice = Math::UnitRandom(); float chance = chance1 * chance2; if(dice < chance) { return true; } else { return false; } } return true; } void OgreCubeMapRenderingRun::freeAllResources() { this->cubemapTexture = 0; TextureManager::getSingleton().remove(name); Root::getSingleton()._getCurrentSceneManager()->destroyCamera(name + "_CAMERA"); }