Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void OfflineLPV::regenVolume()
- {
- Box3F worldBox = getWorldBox();
- Point3F bottom_corner = worldBox.minExtents;
- Point3F top_corner = worldBox.maxExtents;
- Point3F wsVoxelSize = getWorldSpaceVoxelSize();
- Point3I voxelCount = getVoxelCount();
- mTextureCache.clear();
- //get our editor status bar so we can keep tabs on progress
- GuiTextCtrl * statusBarGuiCtrl = dynamic_cast<GuiTextCtrl*>(Sim::findObject("EWorldEditorStatusBarInfo"));
- String statusBarGuiText = "";
- if (statusBarGuiCtrl)
- {
- statusBarGuiText = statusBarGuiCtrl->getText();
- statusBarGuiCtrl->setText("Beginning Regen of the LPV. Clearing old LPV data.");
- }
- RayInfo rayInfo;
- rayInfo.generateTexCoord = true;
- SceneContainer* container = getContainer();
- if ( !container ) return;
- // Allocate our grids.
- SAFE_DELETE_ARRAY(mGeometryGrid);
- SAFE_DELETE_ARRAY(mLightGrid);
- SAFE_DELETE_ARRAY(mPropagatedLightGridA);
- SAFE_DELETE_ARRAY(mPropagatedLightGridB);
- mGeometryGrid = new GeometryVoxel[voxelCount.x * voxelCount.y * voxelCount.z];
- mLightGrid = new SHVoxel[voxelCount.x * voxelCount.y * voxelCount.z];
- mPropagatedLightGridA = new SHVoxel[voxelCount.x * voxelCount.y * voxelCount.z];
- mPropagatedLightGridB = new SHVoxel[voxelCount.x * voxelCount.y * voxelCount.z];
- // Initialize the volume textures (if they aren't already.)
- _initVolumeTextures(voxelCount);
- mPropagationStage = 0;
- mPropagatedLightGrid = mPropagatedLightGridA;
- mDebugVoxels.clear();
- //Step one, we poll the scene container and find all objects that overlap with us
- SphereF sphere;
- sphere.center = (worldBox.minExtents + worldBox.maxExtents) * 0.5;
- VectorF bv = worldBox.maxExtents - sphere.center;
- sphere.radius = bv.len();
- if (statusBarGuiCtrl)
- {
- statusBarGuiCtrl->setText("Voxelizing Static Geometry. 0% complete.");
- }
- S32 processedTris = 0;
- S32 totalTris = 0;
- Vector<OptimizedPolyList> polyLists;
- SimpleQueryList sql;
- container->findObjects(worldBox, STATIC_COLLISION_TYPEMASK, SimpleQueryList::insertionCallback, &sql);
- for (U32 i = 0; i < sql.mList.size(); i++)
- {
- OptimizedPolyList polyList;
- sql.mList[i]->buildPolyList(PLC_Export, &polyList, worldBox, sphere);
- polyLists.push_back(polyList);
- totalTris += polyList.mPolyList.size();
- }
- for (U32 i = 0; i < polyLists.size(); i++)
- {
- if (!polyLists[i].isEmpty())
- {
- Vector<U32> tempIndices;
- tempIndices.reserve(4);
- for (U32 j = 0; j < polyLists[i].mPolyList.size(); j++)
- {
- const OptimizedPolyList::Poly& poly = polyLists[i].mPolyList[j];
- if (poly.vertexCount < 3)
- continue;
- tempIndices.setSize(poly.vertexCount);
- dMemset(tempIndices.address(), 0, poly.vertexCount);
- if (poly.type == OptimizedPolyList::TriangleStrip||
- poly.type == OptimizedPolyList::TriangleFan)
- {
- tempIndices[0] = 0;
- U32 idx = 1;
- for (U32 k = 1; k < poly.vertexCount; k += 2)
- tempIndices[idx++] = k;
- for (U32 k = ((poly.vertexCount - 1) & (~0x1)); k > 0; k -= 2)
- tempIndices[idx++] = k;
- }
- else if (poly.type == OptimizedPolyList::TriangleList)
- {
- for (U32 k = 0; k < poly.vertexCount; k++)
- tempIndices[k] = k;
- }
- else
- continue;
- const U32& firstIdx = polyLists[i].mIndexList[poly.vertexStart];
- const OptimizedPolyList::VertIndex& firstVertIdx = polyLists[i].mVertexList[firstIdx];
- for (U32 k = 1; k < poly.vertexCount - 1; k++)
- {
- const U32& secondIdx = polyLists[i].mIndexList[poly.vertexStart + tempIndices[k]];
- const U32& thirdIdx = polyLists[i].mIndexList[poly.vertexStart + tempIndices[k + 1]];
- const OptimizedPolyList::VertIndex& secondVertIdx = polyLists[i].mVertexList[secondIdx];
- const OptimizedPolyList::VertIndex& thirdVertIdx = polyLists[i].mVertexList[thirdIdx];
- Point3F vertA = polyLists[i].mPoints[firstVertIdx.vertIdx];
- Point3F vertB = polyLists[i].mPoints[secondVertIdx.vertIdx];
- Point3F vertC = polyLists[i].mPoints[thirdVertIdx.vertIdx];
- Point2F uvA = polyLists[i].mUV0s[firstVertIdx.uv0Idx];
- Point2F uvB = polyLists[i].mUV0s[secondVertIdx.uv0Idx];
- Point2F uvC = polyLists[i].mUV0s[thirdVertIdx.uv0Idx];
- //First, test if any of them are contained inside. If they are, we're done
- if (worldBox.isContained(vertA) || worldBox.isContained(vertB) || worldBox.isContained(vertC))
- {
- //can only do 65000 verts in a call, so split it up
- if (mDebugRender.wireMeshRender.bufferData.empty() || mDebugRender.wireMeshRender.bufferData.last().triCount >= 21666)
- {
- DebugRenderStash::WireMeshData::data newBufferData;
- mDebugRender.wireMeshRender.bufferData.push_back(newBufferData);
- }
- mDebugRender.wireMeshRender.bufferData.last().triCount++;
- mDebugRender.wireMeshRender.bufferData.last().vertA.push_back(vertA);
- mDebugRender.wireMeshRender.bufferData.last().vertB.push_back(vertB);
- mDebugRender.wireMeshRender.bufferData.last().vertC.push_back(vertC);
- PlaneF triPlane = PlaneF(vertA, vertB, vertC);
- Point3F triCenter = (vertA + vertB + vertC) / 3;
- Box3F triBox;
- Vector<Point3F> verts;
- verts.push_back(vertA);
- verts.push_back(vertB);
- verts.push_back(vertC);
- triBox = Box3F::aroundPoints(verts.address(), verts.size());
- //get the voxels our tri's bounds overlap
- Point3I minExtIdx = getVoxel(triBox.minExtents);
- Point3I maxExtIdx = getVoxel(triBox.maxExtents);
- U32 xVoxCount = mAbs(maxExtIdx.x - minExtIdx.x);
- U32 yVoxCount = mAbs(maxExtIdx.y - minExtIdx.y);
- U32 zVoxCount = mAbs(maxExtIdx.z - minExtIdx.z);
- xVoxCount = xVoxCount > 0 ? xVoxCount : 1;
- yVoxCount = yVoxCount > 0 ? yVoxCount : 1;
- zVoxCount = zVoxCount > 0 ? zVoxCount : 1;
- U32 xStart = maxExtIdx.x > minExtIdx.x ? minExtIdx.x : maxExtIdx.x;
- U32 yStart = maxExtIdx.y > minExtIdx.y ? minExtIdx.y : maxExtIdx.y;
- U32 zStart = maxExtIdx.z > minExtIdx.z ? minExtIdx.z : maxExtIdx.z;
- //now, iterate through the smaller subset of voxels that this encompasses, and test them. Early out if it isn't valid
- for (U32 x = xStart; x < xStart + xVoxCount; x++)
- {
- for (U32 y = yStart; y < yStart + yVoxCount; y++)
- {
- for (U32 z = zStart; z < zStart + zVoxCount; z++)
- {
- S32 voxIndex = getVoxelIndex(x, y, z);
- if (voxIndex == -1)
- continue;
- ColorF voxel_color = ColorF(0, 0, 0, 0);
- bool emissive = false;
- Box3F voxBox = Box3F(bottom_corner + Point3F(mVoxelSize * x, mVoxelSize * y, mVoxelSize * z),
- bottom_corner + Point3F(mVoxelSize * (x + 1), mVoxelSize * (y + 1), mVoxelSize * (z + 1)));
- if (triPlane.whichSide(voxBox) == PlaneF::Side::On)
- {
- //early out test. If the box containts any or all of the verts, it's assumed to intersect
- bool containsVertA = voxBox.isContained(vertA);
- bool containsVertB = voxBox.isContained(vertB);
- bool containsVertC = voxBox.isContained(vertC);
- if (containsVertA || containsVertB || containsVertC)
- {
- voxel_color = ColorF(255, 255, 255, 255);
- if ( poly.material > -1 )
- {
- Point2F uv;
- if ( containsVertA ) uv = uvA;
- if ( containsVertB ) uv = uvB;
- if ( containsVertC ) uv = uvC;
- Material* mat = dynamic_cast<Material*>(polyLists[i].mMaterialList[poly.material]->getMaterial());
- if (mat)
- {
- Resource<GBitmap> diffuseTex = getOrCreateTexture(mat->mDiffuseMapFilename[0]);
- if (diffuseTex != NULL)
- {
- voxel_color = diffuseTex->sampleTexel(uv.x, uv.y)*mat->mDiffuse[0];
- } else {
- voxel_color = mat->mDiffuse[0];
- }
- voxel_color.red = x / xVoxCount;
- voxel_color.green = y / yVoxCount;
- voxel_color.blue = z / zVoxCount;
- emissive = mat->mEmissive[0];
- }
- }
- U32 voxelIdx = getVoxelIndex(x, y, z);
- mGeometryGrid[voxelIdx].color = voxel_color;
- }
- else
- {
- //first, test if any of the tri edges intersect the box
- F32 collideAPos;
- Point3F collideANorm;
- bool collideA = voxBox.collideLine(vertA, vertB, &collideAPos, &collideANorm);
- F32 collideBPos;
- Point3F collideBNorm;
- bool collideB = voxBox.collideLine(vertB, vertC, &collideBPos, &collideBNorm);
- F32 collideCPos;
- Point3F collideCNorm;
- bool collideC = voxBox.collideLine(vertC, vertA, &collideCPos, &collideCNorm);
- if (collideA || collideB || collideC)
- {
- voxel_color = ColorF(255, 255, 255, 255);
- if ( poly.material > -1 )
- {
- Point2F uv;
- if ( collideA ) uv = uvA + (collideAPos * (uvB - uvA));
- if ( collideB ) uv = uvB + (collideBPos * (uvC - uvB));
- if ( collideC ) uv = uvC + (collideCPos * (uvA - uvC));
- Material* mat = dynamic_cast<Material*>(polyLists[i].mMaterialList[poly.material]->getMaterial());
- if (mat)
- {
- Resource<GBitmap> diffuseTex = getOrCreateTexture(mat->mDiffuseMapFilename[0]);
- if (diffuseTex != NULL)
- {
- voxel_color = diffuseTex->sampleTexel(uv.x, uv.y)*mat->mDiffuse[0];
- } else {
- voxel_color = mat->mDiffuse[0];
- }
- voxel_color.red = x / xVoxCount;
- voxel_color.green = y / yVoxCount;
- voxel_color.blue = z / zVoxCount;
- emissive = mat->mEmissive[0];
- }
- }
- //indeed it does
- U32 voxelIdx = getVoxelIndex(x, y, z);
- mGeometryGrid[voxelIdx].color = voxel_color;
- mGeometryGrid[voxelIdx].emissive = emissive;
- }
- else
- {
- //it doesn't, so we have to test if the voxel intersects the tri(like in cases where the triangle is larger than the voxel)
- //we do this second because it requires more tests and is thus slower.
- for (U32 e = 0; e < BoxBase::Edges::NUM_EDGES; e++)
- {
- BoxBase::Points a, b;
- voxBox.getEdgePointIndices((BoxBase::Edges)e, a, b);
- Point3F edgeA = voxBox.computeVertex(a);
- Point3F edgeB = voxBox.computeVertex(b);
- Point3F intersect;
- if (triPlane.clipSegment(edgeA, edgeB, intersect))
- //if (MathUtils::mLineTriangleCollide(edgeA, edgeB, vertA, vertB, vertC, NULL, &t))
- {
- if (intersect == edgeA || intersect == edgeB)
- continue;
- voxel_color = ColorF(255, 255, 255, 255);
- if ( poly.material > -1 )
- {
- VectorF f1 = vertA - intersect;
- VectorF f2 = vertB - intersect;
- VectorF f3 = vertC - intersect;
- F32 a = mCross(vertA - vertB, vertA - vertC).magnitudeSafe();
- F32 a1 = mCross(f2, f3).magnitudeSafe() / a;
- F32 a2 = mCross(f3, f1).magnitudeSafe() / a;
- F32 a3 = mCross(f1, f2).magnitudeSafe() / a;
- Point2F uv = (uvA * a1) + (uvB * a2) + (uvC * a3);
- Material* mat = dynamic_cast<Material*>(polyLists[i].mMaterialList[poly.material]->getMaterial());
- if (mat)
- {
- Resource<GBitmap> diffuseTex = getOrCreateTexture(mat->mDiffuseMapFilename[0]);
- if (diffuseTex != NULL)
- {
- voxel_color = diffuseTex->sampleTexel(uv.x, uv.y)*mat->mDiffuse[0];
- } else {
- voxel_color = mat->mDiffuse[0];
- }
- voxel_color.red = x / xVoxCount;
- voxel_color.green = y / yVoxCount;
- voxel_color.blue = z / zVoxCount;
- emissive = mat->mEmissive[0];
- }
- }
- U32 voxelIdx = getVoxelIndex(x, y, z);
- mGeometryGrid[voxelIdx].color = voxel_color;
- mGeometryGrid[voxelIdx].emissive = emissive;
- break;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- processedTris++;
- if (statusBarGuiCtrl)
- {
- char buff[256];
- F32 percetile = processedTris / totalTris;
- dSprintf(buff, 256, "Voxelizing Static Geometry. %g % complete.", percetile);
- statusBarGuiCtrl->setText(buff);
- }
- }
- }
- }
- if (statusBarGuiCtrl)
- {
- statusBarGuiCtrl->setText(statusBarGuiText);
- }
- mTextureCache.clear();
- //_rebuildDebugVoxels();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement