//----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- void calculateWorldBounds(bool includeSimMod) { float tileScale = TerrainGlobals.getTerrain().getTileScale(); mWorldMin = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min; mWorldMax = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max; mWorldMin.Y -= 1.0f; mWorldMax.Y += 1.0f; mWorldMin.X = (float)Math.Floor(mWorldMin.X); mWorldMin.Y = (float)Math.Floor(mWorldMin.Y); mWorldMin.Z = (float)Math.Floor(mWorldMin.Z); mWorldMax.X = (float)Math.Ceiling(mWorldMax.X); mWorldMax.Y = (float)Math.Ceiling(mWorldMax.Y); mWorldMax.Z = (float)Math.Ceiling(mWorldMax.Z); if (includeSimMod) { //include any bounding boxes from objects we're including.. BBoundingBox bb = SimGlobals.getSimMain().getBBoxForDecalObjects(); bb.addPoint(mWorldMax); bb.addPoint(mWorldMin); mWorldMin.Y = bb.min.Y; mWorldMax.Y = bb.max.Y; } if (mWorldMin.X < 0) { mWorldMin.X = 0; } if (mWorldMin.Z < 0) { mWorldMin.Z = 0; } }
private BBoundingBox axisPlaneBox(int axis) { BBoundingBox bbox = new BBoundingBox(); bbox.min.X = -0.1f; bbox.min.Y = -0.1f; bbox.min.Z = -0.1f; float hl = mRodLength / 3.0f; if (axis == 0) //X { bbox.max.X = hl; bbox.max.Y = hl; bbox.max.Z = 0.1f; } else if (axis == 1) //Y { bbox.max.X = mRodLength * 0.75f; bbox.max.Y = 0.1f; bbox.max.Z = mRodLength * 0.75f; } else if (axis == 2) //Z { bbox.max.X = 0.1f; bbox.max.Y = hl; bbox.max.Z = hl; } bbox.min *= mVisibleScale.Y; bbox.max *= mVisibleScale.Y; return(bbox); }
//selection testing private BBoundingBox axisRodBox(int axis) { BBoundingBox bbox = new BBoundingBox(); bbox.min.X = -mRodWidth; bbox.min.Y = -mRodWidth; bbox.min.Z = -mRodWidth; if (axis == 0) //X { bbox.max.X = mRodLength + 0.7f;; bbox.max.Y = mRodWidth; bbox.max.Z = mRodWidth; } else if (axis == 1) //Y { bbox.max.X = mRodWidth; bbox.max.Y = mRodLength + 0.7f;; bbox.max.Z = mRodWidth; } else if (axis == 2) //Z { bbox.max.X = mRodWidth; bbox.max.Y = mRodWidth; bbox.max.Z = mRodLength + 0.7f;; } bbox.min *= mVisibleScale.Y; bbox.max *= mVisibleScale.Y; return(bbox); }
//world grid management static private void addLightToGrid(lightInstance light) { LocalLight l = light.mSimEditorObject; BBoundingBox bb = new BBoundingBox(); bb.addPoint(l.mAABB.min); bb.addPoint(l.mAABB.max); bb.min += l.getPosition(); bb.max += l.getPosition(); //walk every world chunk, update our bounds, do intersections BBoundingBox worldAABB = new BBoundingBox(); for (int x = 0; x < mWorldChunks.GetLength(0); x++) { for (int y = 0; y < mWorldChunks.GetLength(1); y++) { worldAABB.max = mWorldChunks[x, y].mQNPointer.getDesc().m_maxPostDeform; worldAABB.min = mWorldChunks[x, y].mQNPointer.getDesc().m_minPostDeform; worldAABB.max.Y = 300; worldAABB.min.Y = -300; if (bb.intersect(worldAABB)) { mWorldChunks[x, y].mLightsAffectingMe.Add(light); light.mWorldChunksImAffecting.Add(mWorldChunks[x, y]); } } } }
void findMaxsMinsRange(ref Vector3 max, ref Vector3 mid, ref Vector3 range) { BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB(); max = bb.max; mid = bb.min; range = (max - mid) * 2.1f; mid = range * 0.5f; mid.X = rangeCompact(mid.X); mid.Y = rangeCompact(mid.Y); mid.Z = rangeCompact(mid.Z); range = (mid * 2.1f); if (range.X == 0) { mid.X = 0; range.X = 1; } if (range.Y == 0) { mid.Y = 0; range.Y = 1; } if (range.Z == 0) { mid.Z = 0; range.Z = 1; } }
void calculateWorldBounds(ref Vector3 mWorldMin, ref Vector3 mWorldMax, ref BBoundingBox worldBounds, bool renderWorldObjects) { float tileScale = TerrainGlobals.getTerrain().getTileScale(); mWorldMin = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min; // -new Vector3(tileScale, tileScale, tileScale); mWorldMax = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max; // +new Vector3(tileScale, tileScale, tileScale); mWorldMin.Y -= 1.0f; mWorldMax.Y += 1.0f; mWorldMin.X = (float)Math.Floor(mWorldMin.X); mWorldMin.Y = (float)Math.Floor(mWorldMin.Y); mWorldMin.Z = (float)Math.Floor(mWorldMin.Z); mWorldMax.X = (float)Math.Ceiling(mWorldMax.X); mWorldMax.Y = (float)Math.Ceiling(mWorldMax.Y); mWorldMax.Z = (float)Math.Ceiling(mWorldMax.Z); //CLM TEMPORARY!!! //if(renderWorldObjects) //{ // //include any bounding boxes from objects we're including.. // BBoundingBox bb = SimGlobals.getSimMain().getBBoxForAOObjects(); // bb.addPoint(mWorldMax); // bb.addPoint(mWorldMin); // mWorldMin.Y = bb.min.Y; // mWorldMax.Y = bb.max.Y; //} worldBounds.min = mWorldMin; worldBounds.min.Y -= 2; worldBounds.max = mWorldMax; worldBounds.max.Y += 2; }
void computeViewToProj(ref Vector3 rayDir, BBoundingBox worldBounds, Matrix worldToView, out Matrix viewToProj, int numXSegments, int numYSegments, int xSegment, int ySegment) { BBoundingBox viewBounds = new BBoundingBox(); for (int i = 0; i < 8; i++) { Vector3 corner = worldBounds.getCorner((BBoundingBox.eCornerIndex)i); Vector4 viewCorner = Vector3.Transform(corner, worldToView); viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z); } float minZ = viewBounds.min.Z; // *0.5f; float maxZ = viewBounds.max.Z; // *2; float distanceX = Math.Abs(viewBounds.max.X - viewBounds.min.X); float segSizeX = distanceX / numXSegments; float distanceY = Math.Abs(viewBounds.max.Y - viewBounds.min.Y); float segSizeY = distanceY / numYSegments; float minXSeg = viewBounds.min.X + (segSizeX * xSegment); float minYSeg = viewBounds.min.Y + (segSizeY * ySegment); viewToProj = Matrix.OrthoOffCenterLH( minXSeg, minXSeg + segSizeX, minYSeg, minYSeg + segSizeY, minZ, maxZ); }
float calcAdjustedMidValue(float inputMid) { BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB(); float diff = bb.max.Y - bb.min.Y; int qDiff = (int)(diff / 100) * 2; float adjustedMid = qDiff / 10.0f; return(inputMid - adjustedMid); }
Vector3 calcAdjustedMidValue(Vector3 inputMid) { BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB(); Vector3 diff = bb.max - bb.min; int qDiff = (int)(diff.Y / 100) * 2; Vector3 adjustedMid = new Vector3(0, qDiff / 10.0f, 0); return(inputMid - adjustedMid); }
static public BBoundingBox giveMaxBBs() { BBoundingBox bb = new BBoundingBox(); bb.empty(); for (int i = 0; i < getNumSets(); i++) { bb.addPoint(mFoliageSets[i].mBBMin); bb.addPoint(mFoliageSets[i].mBBMax); } return(bb); }
private bool testPlanesIntersection(Vector3 r0, Vector3 rD) { mHitDist[0] = float.MaxValue; mHitDist[1] = float.MaxValue; mHitDist[2] = float.MaxValue; Vector3 tc = Vector3.Empty; Vector3 tOrg = r0 - mTranslation; BBoundingBox yxBox = axisPlaneBox(0); if (!BMathLib.ray3AABB(ref tc, ref mHitDist[0], ref tOrg, ref rD, ref yxBox.min, ref yxBox.max)) { mHitDist[0] = float.MaxValue; } BBoundingBox zxBox = axisPlaneBox(1); if (!BMathLib.ray3AABB(ref tc, ref mHitDist[1], ref tOrg, ref rD, ref zxBox.min, ref zxBox.max)) { mHitDist[1] = float.MaxValue; } BBoundingBox yzBox = axisPlaneBox(2); if (!BMathLib.ray3AABB(ref tc, ref mHitDist[2], ref tOrg, ref rD, ref yzBox.min, ref yzBox.max)) { mHitDist[2] = float.MaxValue; } if (mHitDist[0] < mHitDist[1] && mHitDist[0] < mHitDist[2]) { mXaxisSelected = mYaxisSelected = true; } else if (mHitDist[1] < mHitDist[0] && mHitDist[1] < mHitDist[2]) { mXaxisSelected = mZaxisSelected = true; } else if (mHitDist[2] < mHitDist[1] && mHitDist[2] < mHitDist[0]) { mZaxisSelected = mYaxisSelected = true; } return(mXaxisSelected | mYaxisSelected | mZaxisSelected); }
void findMaxsMinsRange(ref float max, ref float mid, ref float range) { BBoundingBox bb = TerrainGlobals.getTerrain().getDisplacementBB(); max = bb.max.Y; mid = bb.min.Y; range = (max - mid) * 2.1f; mid = range * 0.5f; mid = rangeCompact(mid); range = (mid * 2.1f); if (range == 0) { mid = 0; range = 1; } }
void calculateWorldBounds(ref Vector3 mWorldMin, ref Vector3 mWorldMax, ref BBoundingBox worldBounds, bool renderWorldObjects) { float tileScale = TerrainGlobals.getTerrain().mTileScale; mWorldMin = TerrainGlobals.getTerrain().mTerrainBBMin; // -new Vector3(tileScale, tileScale, tileScale); mWorldMax = TerrainGlobals.getTerrain().mTerrainBBMax; // +new Vector3(tileScale, tileScale, tileScale); mWorldMin.Y -= 1.0f; mWorldMax.Y += 1.0f; mWorldMin.X = (float)Math.Floor(mWorldMin.X); mWorldMin.Y = (float)Math.Floor(mWorldMin.Y); mWorldMin.Z = (float)Math.Floor(mWorldMin.Z); mWorldMax.X = (float)Math.Ceiling(mWorldMax.X); mWorldMax.Y = (float)Math.Ceiling(mWorldMax.Y); mWorldMax.Z = (float)Math.Ceiling(mWorldMax.Z); worldBounds.min = mWorldMin; worldBounds.min.Y -= 2; worldBounds.max = mWorldMax; worldBounds.max.Y += 2; }
private bool testRodsIntersection(Vector3 r0, Vector3 rD) { Vector3 coord = Vector3.Empty; float t = 0; Vector3 tOrg = r0 - mTranslation; BBoundingBox xBox = axisRodBox(0); mXaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref xBox.min, ref xBox.max); BBoundingBox yBox = axisRodBox(1); mYaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref yBox.min, ref yBox.max); BBoundingBox zBox = axisRodBox(2); mZaxisSelected = BMathLib.ray3AABB(ref coord, ref t, ref tOrg, ref rD, ref zBox.min, ref zBox.max); return(mXaxisSelected | mYaxisSelected | mZaxisSelected); }
//-------------------------------------------------------------------------- void computeTransforms(ref Vector3 rayDir, out Matrix worldToView, out Matrix viewToProj) { Vector3 mWorldMin = mScene.getWorldMin(); Vector3 mWorldMax = mScene.getWorldMax(); Vector3 eyePos = new Vector3((mWorldMin.X + mWorldMax.X) * .5f, mWorldMax.Y + 50.0f, (mWorldMin.Z + mWorldMax.Z) * .5f); Vector3 focusPos = eyePos; focusPos.Y -= 1; Vector3 upDir = BMathLib.unitZ; worldToView = Matrix.LookAtLH(eyePos, focusPos, upDir); BBoundingBox worldBounds = new BBoundingBox(); worldBounds.min = mWorldMin; worldBounds.min.Y -= 2; //for depth peeling worldBounds.max = mWorldMax; worldBounds.max.Y += 2; //for depth peeling BBoundingBox viewBounds = new BBoundingBox(); for (int i = 0; i < 8; i++) { Vector3 corner = worldBounds.getCorner((BBoundingBox.eCornerIndex)i); Vector4 viewCorner = Vector3.Transform(corner, worldToView); viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z); } float minZ = viewBounds.min.Z; float maxZ = viewBounds.max.Z; float offsetX = 0.5f / (viewBounds.max.X - viewBounds.min.X); float offsetY = 0;// -0.5f / (viewBounds.max.Y - viewBounds.min.Y); viewToProj = Matrix.OrthoOffCenterLH( viewBounds.min.X + offsetX, viewBounds.max.X + offsetX, viewBounds.min.Y + offsetY, viewBounds.max.Y + offsetY, minZ, maxZ); }
//-------------------------------------------------------------------------- void computeTransforms(Vector3 upDir, ref Matrix worldToView, ref Matrix viewToProj, ref BBoundingBox worldBounds, ref double worldMinY, ref double worldMaxY) { float diameter = Vector3.Length(mWorldMax - mWorldMin); float radius = diameter * 0.5f; Vector3 worldCenter = (mWorldMax - mWorldMin) * 0.5f; Vector3 eyePos = worldCenter + (BMathLib.unitY * radius); Vector3 focusPos = worldCenter; worldToView = Matrix.LookAtLH(eyePos, focusPos, upDir); worldBounds.min = mWorldMin; // worldBounds.min.Y -= 2; worldBounds.max = mWorldMax; // worldBounds.max.Y += 2; //worldBounds.max.X += 1; //CLM WHAT? //worldBounds.max.Z += 1; //CLM WHAT? BBoundingBox viewBounds = new BBoundingBox(); for (int i = 0; i < 8; i++) { Vector3 corner = worldBounds.getCorner((BBoundingBox.eCornerIndex)i); Vector4 viewCorner = Vector3.Transform(corner, worldToView); viewBounds.addPoint(viewCorner.X, viewCorner.Y, viewCorner.Z); } float minZ = viewBounds.min.Z; // *0.5f; float maxZ = viewBounds.max.Z; // *2; viewToProj = Matrix.OrthoOffCenterLH( viewBounds.min.X, viewBounds.max.X, viewBounds.min.Y, viewBounds.max.Y, minZ, maxZ); worldMinY = eyePos.Y + -minZ; worldMaxY = eyePos.Y + -maxZ; }
public override bool testIntersection() { if (mLocked) { return(true); } mXaxisSelected = mYaxisSelected = mZaxisSelected = false; //cast a ray //find what axis it's hitting.. Point cursorPos = new Point(); UIManager.GetCursorPos(ref cursorPos); Vector3 orig = BRenderDevice.getRayPosFromMouseCoords(false, cursorPos); Vector3 dir = BRenderDevice.getRayPosFromMouseCoords(true, cursorPos) - orig; dir = BMathLib.Normalize(dir); //test intersection against our entire widget first BBoundingBox myBox = new BBoundingBox(); myBox.min = mTranslation - (new Vector3(mRodWidth, mRodWidth, mRodWidth) * mVisibleScale.Y); myBox.max = mTranslation + (new Vector3(mRodLength + 0.5f, mRodLength + 0.5f, mRodLength + 0.5f) * mVisibleScale.Y); if (!myBox.intersect(orig, dir)) { return(false); } //if we didn't hit a plane, check our boxes if (!testPlanesIntersection(orig, dir)) { testRodsIntersection(orig, dir); } return(mXaxisSelected | mYaxisSelected | mZaxisSelected); }
public void updateBoundsFromChildren() { if (mChildren != null) { BBoundingBox aabb = new BBoundingBox(); for (uint i = 0; i < (int)eQNKidEnum.cNumQuadTreeKids; i++) { if (mChildren[i] == null) { continue; } mChildren[i].updateBoundsFromChildren(); float3 min = mChildren[i].getAABBMin(); aabb.addPoint(min.X, min.Y, min.Z); min = mChildren[i].getAABBMax(); aabb.addPoint(min.X, min.Y, min.Z); } mAABBMin = new float3(aabb.min); mAABBMax = new float3(aabb.max); aabb = null; } }
void recalculateCellBB(SpatialQuadTreeCell spatialCell) { BBoundingBox bb = new BBoundingBox(); bb.empty(); RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)spatialCell.mExternalData); for (uint i = (uint)cell.mMinXVert; i <= cell.mMinXVert + mNumXVertsPerCell; i++) { for (uint j = (uint)cell.mMinZVert; j <= cell.mMinZVert + mNumZVertsPerCell; j++) { if (i >= mWidth || j >= mHeight) { continue; } float3 worldPos = getWorldspacePoint((int)i, (int)j); bb.addPoint(worldPos.toVec3()); } } spatialCell.setBounds(new float3(bb.min), new float3(bb.max)); bb = null; }
private void generateGridChunks(ref XTDVisualHeader header) { //Create and write our flat terrain quadnode chunks BTerrainQuadNode[] mLeafNodes = TerrainGlobals.getTerrain().getQuadNodeLeafArray(); for (int i = 0; i < mLeafNodes.Length; i++) { int width = (int)BTerrainQuadNode.getMaxNodeWidth(); ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder(); chunkHolder.mDataMemStream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream); XTDTerrainChunk gridNode = new XTDTerrainChunk(); int locX = mLeafNodes[i].getDesc().mMinXVert / width; int locZ = mLeafNodes[i].getDesc().mMinZVert / width; gridNode.gridLocX = locX; gridNode.gridLocZ = locZ; //calculate our chunk data gridNode.heightmapOnly = false; gridNode.maxVertStride = 64; //lets get our verts, normals, and ambOcclu int mnX = locX * width; int mnZ = locZ * width; BBoundingBox bb = new BBoundingBox(); bb.empty(); for (int z = 0; z < width + 1; z++) { for (int x = 0; x < width + 1; x++) { int xVal = (int)(mnX + x); int zVal = (int)(mnZ + z); Vector3 v = TerrainGlobals.getTerrain().getPos(xVal, zVal); bb.addPoint(v); } } gridNode.mMin = bb.min; gridNode.mMax = bb.max; //IF WE CONTAIN FOLIAGE! increase the size of our bounding boxes.. if (FoliageManager.isChunkUsed(mLeafNodes[i])) { BBoundingBox bbA = FoliageManager.giveMaxBBs(); gridNode.mMin += bbA.min; gridNode.mMax += bbA.max; } //expand our box a tad float scle = TerrainGlobals.getTerrain().getTileScale(); gridNode.mMin -= new Vector3(scle, scle, scle); gridNode.mMax += new Vector3(scle, scle, scle); //send the verts off to the compressor to be compressed properly into an image (using whatever technique) //be sure to assign a corolary ID so we can reference it later. writeChunk(gridNode, binWriter); //add this chunk to our main data stream ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_TerrainChunk, chunkHolder, binWriter.BaseStream.Length); binWriter.Close(); binWriter = null; chunkHolder.Close(); chunkHolder = null; } mLeafNodes = null; }
public bool export_XTD(string filename, ExportSettings expSettings, ref ExportResults results) { DateTime start = DateTime.Now; //write the header for the entire XTD file XTDVisualHeader header = new XTDVisualHeader(); header.version = (int)eFileVersions.cXTDVersion; header.numXVerts = TerrainGlobals.getTerrain().getNumXVerts(); header.numXChunks = (int)(TerrainGlobals.getTerrain().getNumXVerts() / BTerrainQuadNode.cMaxWidth); header.tileScale = TerrainGlobals.getTerrain().getTileScale(); BBoundingBox simRepBB = SimGlobals.getSimMain().getBBoxForDecalObjects(); Vector3 visRepMin = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min - new Vector3(0, header.tileScale, 0); Vector3 visRepMax = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max + new Vector3(0, header.tileScale, 0); if (!CoreGlobals.mbLoadTerrainVisRep) { visRepMin = simRepBB.min; visRepMax = simRepBB.max; } header.worldMin = visRepMin; header.worldMax = visRepMax; header.endianSwap(); //write our header first. ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder(); chunkHolder.mDataMemStream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream); binWriter.Write(ExportTo360.StructToByteArray(header)); ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_XTDHeader, chunkHolder, (int)chunkHolder.mDataMemStream.Length); binWriter.Close(); binWriter = null; chunkHolder.Close(); chunkHolder = null; header.endianSwap(); generateGridChunks(ref header); writeAtlasToMemory(ref results); writeAOData(ref results); writeAlpha(ref results); writeTessData(expSettings.RefineTerrain, expSettings.RefineEpsilon, expSettings.RefineMinorityBias, ref results); writeLightData(ref expSettings, ref results); bool exportOK = ExportTo360.safeECFFileWrite(filename, ".XTD"); TimeSpan ts = DateTime.Now - start; results.totalTime = ts.TotalMinutes; return(exportOK); }
public void calcualteAO(eAOQuality quality, bool renderWorldObjects, ref float totalTime, ref float peelTime, ref float gatherTime, int startSampleIndex, int endSampleIndex) { totalTime = 0; peelTime = 0; gatherTime = 0; DateTime n = DateTime.Now; //should we multithread? if (CoreGlobals.mProcessorInfo.NumLogicalProcessors > 1) { mUsingMultithreading = true; AmbientOcclusion.IncrementCount = 0; AOIncrements = new int[TerrainGlobals.getTerrain().getNumXVerts() * TerrainGlobals.getTerrain().getNumZVerts()]; } else { mUsingMultithreading = false; } int width = 512; int height = 512; int numXSegments = 1; int numYSegments = 1; //special settings for Final mode if (quality == eAOQuality.cAO_Final) { numXSegments = 4; //what should these values really be? numYSegments = 4; // they should scale, so that huge terrain gets more segments.. // width = 1024; // height = 1024; // mUsingMultithreading = false; } //clear any handles available so we can use them as we see fit! TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle(); TerrainGlobals.getVisual().destroyAllHandles(); TerrainGlobals.getVisual().setHandleGenMode(true); blackoutAO(); //so we can gather light data Vector3 mWorldMin = Vector3.Empty; Vector3 mWorldMax = Vector3.Empty; BBoundingBox worldBounds = new BBoundingBox(); calculateWorldBounds(ref mWorldMin, ref mWorldMax, ref worldBounds, renderWorldObjects); mPeeler.init(width, height); Vector3 rayDir = -BMathLib.unitY; rayDir.Normalize(); Matrix worldToView = Matrix.Identity; Matrix viewToProj = Matrix.Identity; int numDesiredSamples = (int)Math.Sqrt((int)quality); int startIndex = 0; int endIndex = numDesiredSamples; List <Vector3> rayDirs = null; if (startSampleIndex != -1) { rayDirs = giveStratifiedOnHemiSphere(0, numDesiredSamples, false); startIndex = startSampleIndex; endIndex = Math.Min(endSampleIndex, rayDirs.Count); } else { rayDirs = giveStratifiedOnHemiSphere(0, numDesiredSamples, true); startIndex = 0; endIndex = rayDirs.Count; } float rcpNumSamples = 1.0f / (float)(rayDirs.Count); int numSamples = endIndex - startIndex; //begin our peel & gather process... bool ownBeginScene = !BRenderDevice.isInSceneRender(); if (ownBeginScene) { BRenderDevice.getDevice().BeginScene(); } for (int dc = startIndex; dc < endIndex; dc++) { //choose one rayDir = -rayDirs[dc]; computeWorldToView(ref rayDir, ref mWorldMin, ref mWorldMax, out worldToView); for (int x = 0; x < numXSegments; x++) { for (int y = 0; y < numYSegments; y++) { //calculate our lightspace projection matrix computeViewToProj(ref rayDir, worldBounds, worldToView, out viewToProj, numXSegments, numYSegments, x, y); //use worker threads.. gatherWorkerData wd = new gatherWorkerData(0, 0, TerrainGlobals.getTerrain().getNumXVerts(), TerrainGlobals.getTerrain().getNumZVerts(), width, height, rayDir, worldToView * viewToProj, rcpNumSamples); mPeeler.mDepthArray = null; mPeeler.mDepthArray = wd.fragList; //create our depth layers DateTime dpn = DateTime.Now; mPeeler.depthPeel(ref rayDir, ref worldToView, ref viewToProj, renderWorldObjects); TimeSpan dpts = DateTime.Now - dpn; peelTime += (float)dpts.TotalMinutes; //do final gathering (AO SPECIFIC) if (mUsingMultithreading) { finalGatherMultiThreaded(wd); } else { DateTime fgn = DateTime.Now; finalGatherSingleThreaded(wd); TimeSpan fgts = DateTime.Now - fgn; gatherTime += (float)fgts.TotalMinutes; } wd = null; mPeeler.mDepthArray = null; } } } if (ownBeginScene) { BRenderDevice.getDevice().EndScene(); } mPeeler.destroy(); TerrainGlobals.getVisual().setHandleGenMode(false); //if we're using multithreading, wait for all our worker threads to finish. if (mUsingMultithreading) { while (AmbientOcclusion.IncrementCount <= numSamples - 1) { Thread.Sleep(1); } float[] AOVals = TerrainGlobals.getEditor().getAmbientOcclusionValues(); for (int i = 0; i < AOIncrements.Length; i++) { AOVals[i] = AOIncrements[i] * rcpNumSamples; } } TimeSpan ts = DateTime.Now - n; totalTime = (float)ts.TotalMinutes; }
public BRenderGrannyMesh() { mPrimitives = new List <BRenderPrimitive>(); mBBox = new BBoundingBox(); }
//----------------------------------------------------------------------------- public void setModelBoundingBox(BBoundingBox box) { mModelBoundingBox = box; mModelBoundingBoxMaxSize = mModelBoundingBox.getMaxSize(); }
public void computeHeightField(uint width, uint height, bool includeSimMod, Vector3 upDir, uint cNumSamples) { copyTempD3DValues(); TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle(); TerrainGlobals.getVisual().destroyAllHandles(); TerrainGlobals.getVisual().setHandleGenMode(true); GC.WaitForPendingFinalizers(); ExportTo360.checkLoadRender(); createTempTextures(width, height); calculateWorldBounds(includeSimMod); mHeightFieldAttributes = new BHeightFieldAttributes(width, height); Matrix worldToView = Matrix.Identity; Matrix viewToProj = Matrix.Identity; BBoundingBox worldBounds = new BBoundingBox(); double worldMinY = 0, worldMaxY = 0; computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY); Random rand = new Random(); double minDepth = float.MaxValue; double maxDepth = float.MinValue; cNumSamples = (uint)BMathLib.Clamp(cNumSamples, 1, 32); for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++) { float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f; float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f; Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f); generateDepthBuffer(ref pHighDepthSurf, width, height, false, worldToView, viewToProj * projOfs, includeSimMod); generateDepthBuffer(ref pLowDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod); fillHeightFieldTexture(width, height, mHeightFieldAttributes, pLowDepths, pHighDepths, ref minDepth, ref maxDepth); } viewToProj = viewToProj * Matrix.Translation(0.0f, 0.0f, (float)(-minDepth)) * Matrix.Scaling(1.0f, 1.0f, (float)(1.0f / (maxDepth - minDepth))); double newWorldMinY = worldMinY + (worldMaxY - worldMinY) * minDepth; worldMaxY = worldMinY + (worldMaxY - worldMinY) * maxDepth; worldMinY = newWorldMinY; minDepth = 0.0f; maxDepth = 1.0f; mHeightFieldAttributes.mWidth = width; mHeightFieldAttributes.mHeight = height; mHeightFieldAttributes.mBounds = worldBounds; mHeightFieldAttributes.mWorldMinY = (float)worldMinY; mHeightFieldAttributes.mWorldMaxY = (float)worldMaxY; mHeightFieldAttributes.mWorldRangeY = (float)(worldMaxY - worldMinY); float minZ = 0; float maxZ = 1; float x = 0; float y = 0; Matrix cMTProjToScreen = BMathLib.matrixFrom16floats( width * .5f, 0.0f, 0.0f, 0.0f, 0.0f, height * -.5f, 0.0f, 0.0f, 0.0f, 0.0f, maxZ - minZ, 0.0f, x + width * .5f, y + height * .5f, minZ, 1.0f); mHeightFieldAttributes.mWorldToNormZ = worldToView * viewToProj * cMTProjToScreen; Matrix screenToProj = Matrix.Invert(cMTProjToScreen); Matrix projToView = Matrix.Invert(viewToProj); Matrix cMTScreenToView = Matrix.Multiply(screenToProj, projToView); mHeightFieldAttributes.mNormZToWorld = cMTScreenToView * Matrix.Invert(worldToView); releaseTempTextures(); restoreTempD3DValues(); TerrainGlobals.getVisual().setHandleGenMode(false); ExportTo360.checkUnloadRender(); //copy our pixels from the previous point { for (int q = 0; q < width; q++) { mHeightFieldAttributes.mpTexelsLO[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsLO[(width - 2) * width + q]; mHeightFieldAttributes.mpTexelsLO[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsLO[q * width + (width - 2)]; mHeightFieldAttributes.mpTexelsLO[q] = mHeightFieldAttributes.mpTexelsLO[width + q]; mHeightFieldAttributes.mpTexelsLO[q * width] = mHeightFieldAttributes.mpTexelsLO[q * width + (1)]; mHeightFieldAttributes.mpTexelsHI[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsHI[(width - 2) * width + q]; mHeightFieldAttributes.mpTexelsHI[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsHI[q * width + (width - 2)]; mHeightFieldAttributes.mpTexelsHI[q] = mHeightFieldAttributes.mpTexelsHI[width + q]; mHeightFieldAttributes.mpTexelsHI[q * width] = mHeightFieldAttributes.mpTexelsHI[q * width + (1)]; } } #region dumpHeightfiled //{ // FileStream s = File.Open(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\out.raw", FileMode.OpenOrCreate, FileAccess.Write); // BinaryWriter f = new BinaryWriter(s); // for (int i = 0; i < width * height; i++) // { // f.Write(mHeightFieldAttributes.mpTexelsLO[i]); // f.Write(mHeightFieldAttributes.mpTexelsHI[i]); // } // f.Close(); // s.Close(); //} #endregion }
//----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- public void computeHeightFieldDirectFloat(uint width, uint height, bool includeSimMod, Vector3 upDir, bool onlyDoOneSample, ref float[] output) { copyTempD3DValues(); TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle(); TerrainGlobals.getVisual().destroyAllHandles(); TerrainGlobals.getVisual().setHandleGenMode(true); GC.WaitForPendingFinalizers(); ExportTo360.checkLoadRender(); createTempTextures(width, height); calculateWorldBounds(includeSimMod); mHeightFieldAttributes = new BHeightFieldAttributes(width, height); Matrix worldToView = Matrix.Identity; Matrix viewToProj = Matrix.Identity; BBoundingBox worldBounds = new BBoundingBox(); double worldMinY = 0, worldMaxY = 0; computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY); float mWorldRangeY = (float)(mWorldMax.Y - mWorldMin.Y); uint numVals = width * height; if (output == null || output.Length != numVals) { output = new float[numVals]; for (uint i = 0; i < numVals; i++) { output[i] = float.MinValue; } } uint cNumSamples = (uint)(onlyDoOneSample?1:4); Random rand = new Random(); for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++) { float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f; float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f; Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f); generateHeightBuffer(ref pHighDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod); #region fill & lock //mWorldMin.Y += 1.0f; //mWorldMax.Y -= 1.0f; unsafe { GraphicsStream texstreamHI = pHighDepths.LockRectangle(0, LockFlags.None); float * pSrcHigh = (float *)texstreamHI.InternalDataPointer; //copy the data out so we can screw with it. for (uint c = 0; c < numVals; c++) { output[c] = (float)Math.Max(output[c], pSrcHigh[c]); } pHighDepths.UnlockRectangle(0); } //find the max & min depth for this slice #endregion } releaseTempTextures(); restoreTempD3DValues(); TerrainGlobals.getVisual().setHandleGenMode(false); ExportTo360.checkUnloadRender(); //#region dumpHeightfiled //{ // FileStream s = File.Open("_outHiDirect.raw", FileMode.OpenOrCreate, FileAccess.Write); // BinaryWriter f = new BinaryWriter(s); // for (int i = 0; i < width * height; i++) // { // float kp = (output[i] - mWorldMin.Y) / mWorldRangeY; // ushort op = (ushort)(kp * ushort.MaxValue); // f.Write(op); // } // f.Close(); // s.Close(); //} //#endregion }
void writeTempModelsToZip(ZipArchive zip) { SceneObjectsXML sceneObjects = new SceneObjectsXML(); BBoundingBox objectAABB = new BBoundingBox(); objectAABB.empty(); string baseDir = CoreGlobals.getWorkPaths().mGameDirectory; if (mIncludeObjects) { //searalize an XML file to memorystream holding position and model names List <EditorObject> editObjs = SimGlobals.getSimMain().getEditorObjects(false, SimMain.eFilterTypes.cFilterAll, -1, false); for (int objIdx = 0; objIdx < editObjs.Count; objIdx++) { if (editObjs[objIdx] == null) { continue; } if (editObjs[objIdx].GetType() == typeof(SimObject)) { SimObject obj = editObjs[objIdx] as SimObject; if (obj.IgnoreToAO) { continue; } if (obj != null && obj.ProtoObject != null) { string grannyName = obj.ProtoObject.getGrannyFileName(); if (grannyName == "") { continue; } if (grannyName.Contains(baseDir)) { grannyName = grannyName.Remove(0, baseDir.Length); } //if this GR2 isn't already listed, then list it. if (!sceneObjects.objectGR2Names.Contains(grannyName)) { sceneObjects.objectGR2Names.Add(grannyName); } //add our instance ObjectInstanceXML inst = new ObjectInstanceXML(); inst.GR2Filename = grannyName; inst.setOrientation(obj.getMatrix()); sceneObjects.objectinstances.Add(inst); //add our transformed BB to the global BB list if (obj != null && obj.mVisual != null) { if (!obj.IgnoreToAO) { objectAABB.addPoint(obj.mAABB.max + obj.getPosition()); objectAABB.addPoint(obj.mAABB.min + obj.getPosition()); } } } } } sceneObjects.aabbmin = TextVectorHelper.ToString(objectAABB.min); sceneObjects.aabbmax = TextVectorHelper.ToString(objectAABB.max); } //write it to an XML stream AbstractFile md = zip.CreateFile("modelPositions.xml", true); Stream stream = md.OpenWrite(true); XmlSerializer s = new XmlSerializer(typeof(SceneObjectsXML), new Type[] { }); s.Serialize(stream, sceneObjects); stream.Close(); //Create a folder and copy our GR2s into it //AbstractFolder fold = zip.CreateFolder("models"); //if (mIncludeObjects) //{ // for (int modelIdx = 0; modelIdx < sceneObjects.objectGR2Names.Count; modelIdx++) // { // if (mWorkerThread.CancellationPending) // return; // try // { // if (fullGR2Names[modelIdx] == "") // continue; // DiskFile modelFile = new DiskFile(fullGR2Names[modelIdx]); // modelFile.CopyTo(fold, true); // } // catch (Exception e) // { // continue; // } // } //} }