//---------------------------------- void getPointsIntersectingSphere(List <int> points, float3 sphereCenter, float sphereRadius) { List <SpatialQuadTreeCell> nodes = new List <SpatialQuadTreeCell>(); getLeafCellsIntersectingSphere(nodes, sphereCenter, sphereRadius); if (nodes.Count == 0) { return; } Vector3 center = sphereCenter.toVec3(); for (int q = 0; q < nodes.Count; q++) { RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)nodes[q].mExternalData); Debug.Assert(cell != null); for (uint i = (uint)cell.mMinXVert; i < (uint)cell.mMinXVert + mNumXVertsPerCell; i++) { for (uint j = (uint)cell.mMinZVert; j < (uint)cell.mMinZVert + mNumZVertsPerCell; j++) { uint index = (uint)((i) + mWidth * (j)); Vector3 vert = getWorldspacePoint((int)(i), (int)(j)).toVec3(); if (BMathLib.pointSphereIntersect(ref center, sphereRadius, ref vert)) { points.Add((int)index); } } } } }
//---------------------------------- public void render(bool renderCursor) { if (!mRenderHeights) { return; } List <SpatialQuadTreeCell> nodes = new List <SpatialQuadTreeCell>(); getVisibleNodes(nodes, TerrainGlobals.getTerrain().getFrustum()); //update any visual handles that need it.. for (int i = 0; i < nodes.Count; i++) { RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)nodes[i].mExternalData); Debug.Assert(cell != null); if (cell.mVisualHandle == null) { cell.mVisualHandle = newVisualHandle((int)cell.mMinXVert, (int)cell.mMinZVert); } renderCell(cell.mVisualHandle); } if (renderCursor) { ((BTerrainCameraBrush)TerrainGlobals.getEditor().getCurrentBrush()).render(); } }
public void recalculateVisuals() { for (uint minx = 0; minx < mNumXLeafCells; minx++) { for (uint minz = 0; minz < mNumZLeafCells; minz++) { SpatialQuadTreeCell spatialCell = getLeafCellAtGridLoc(minx, minz); RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)spatialCell.mExternalData); updateVisualHandle(ref cell.mVisualHandle, cell.mMinXVert, cell.mMinZVert); } } }
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; }
public void updateAfterPainted(int minX, int minZ, int maxX, int maxZ) { //verts are in our local stride. //find any chunks intersecting these numbers and update them. uint minXCell = (uint)BMathLib.Clamp((minX / mNumXVertsPerCell) - 1, 0, mNumXLeafCells); uint minZCell = (uint)BMathLib.Clamp((minZ / mNumZVertsPerCell) - 1, 0, mNumXLeafCells); uint maxXCell = (uint)BMathLib.Clamp((maxX / mNumXVertsPerCell) + 1, 0, mNumXLeafCells); uint maxZCell = (uint)BMathLib.Clamp((maxZ / mNumZVertsPerCell) + 1, 0, mNumXLeafCells); for (uint minx = minXCell; minx < maxXCell; minx++) { for (uint minz = minZCell; minz < maxZCell; minz++) { SpatialQuadTreeCell spatialCell = getLeafCellAtGridLoc(minx, minz); RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)spatialCell.mExternalData); updateVisualHandle(ref cell.mVisualHandle, cell.mMinXVert, cell.mMinZVert); recalculateCellBB(spatialCell); } } mRootCell.updateBoundsFromChildren(); }
bool getClosestIntersectionPoint(float3 rayOrig, float3 rayDir, out float3 intPt) { intPt = float3.Empty; List <SpatialQuadTreeCell> nodes = new List <SpatialQuadTreeCell>(); getLeafCellsIntersectingRay(nodes, rayOrig, rayDir); if (nodes.Count == 0) { return(false); } //walk through each cell returned, do a per polygon intersection with each one.. Vector3 origin = rayOrig.toVec3(); Vector3 dir = rayDir.toVec3(); Vector3 closestIntersect = Vector3.Empty; float closestDist = float.MaxValue; Vector3[] verts = new Vector3[3]; bool hit = false; for (int q = 0; q < nodes.Count; q++) { RealLOSRepQuadCell cell = ((RealLOSRepQuadCell)nodes[q].mExternalData); Debug.Assert(cell != null); int minx = (int)(cell.mMinXVert); int minz = (int)(cell.mMinZVert); for (uint i = 0; i < mNumXVertsPerCell; i++) { for (uint j = 0; j < mNumZVertsPerCell; j++) { int tileI = (int)(minx + i); int tileJ = (int)(minz + j); if (tileI >= mWidth - 1 || tileJ >= mHeight - 1) { continue; } bool tHit = false; Vector3 pt = Vector3.Empty; float[] h = new float[4]; h[0] = getCompositeHeight(tileI, tileJ); h[1] = getCompositeHeight(tileI, tileJ + 1); h[2] = getCompositeHeight(tileI + 1, tileJ); h[3] = getCompositeHeight(tileI + 1, tileJ + 1); if (h[0] != cJaggedEmptyValue && h[3] != cJaggedEmptyValue && h[1] != cJaggedEmptyValue) { verts[0] = new Vector3(tileI * mTileScale, h[0], (tileJ) * mTileScale); verts[1] = new Vector3((tileI + 1) * mTileScale, h[3], (tileJ + 1) * mTileScale); verts[2] = new Vector3(tileI * mTileScale, h[1], (tileJ + 1) * mTileScale); if (BMathLib.raySegmentIntersectionTriangle(verts, ref origin, ref dir, false, ref pt)) { Vector3 vec = pt - origin; //ensure this hit point is the closest to the origin float len = vec.Length(); if (len < closestDist) { closestDist = len; closestIntersect = pt; } hit = true; } } if (h[0] != cJaggedEmptyValue && h[3] != cJaggedEmptyValue && h[2] != cJaggedEmptyValue) { verts[0] = new Vector3(tileI * mTileScale, h[0], (tileJ) * mTileScale); verts[1] = new Vector3((tileI + 1) * mTileScale, h[3], (tileJ + 1) * mTileScale); verts[2] = new Vector3((tileI + 1) * mTileScale, h[2], (tileJ) * mTileScale); if (BMathLib.raySegmentIntersectionTriangle(verts, ref origin, ref dir, false, ref pt)) { Vector3 vec = pt - origin; //ensure this hit point is the closest to the origin float len = vec.Length(); if (len < closestDist) { closestDist = len; closestIntersect = pt; } hit = true; } } } } } intPt.X = closestIntersect.X; intPt.Y = closestIntersect.Y; intPt.Z = closestIntersect.Z; return(hit); }