internal float SampleField(ref Vector3 position) { Vector3 localPosition = position - m_translation; Vector3I samplePos; Vector2 pos = Vector2.Zero; MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); return(GetValueForPosition(ref samplePos, ref pos, true)); }
private float GetValueForPosition(ref Vector3I samplePos, ref Vector2 pos, bool interpolate) { float value = 0.0f; if (interpolate) { float fx = pos.X - samplePos.Y; float fy = pos.Y - samplePos.Z; float fx1 = 1.0f - fx; float fy1 = 1.0f - fy; Vector2I newSamplePos = new Vector2I(samplePos.Y, samplePos.Z); ushort height; int newFacePosition = 0; GetHeightFromBatch(samplePos.X, newSamplePos.X, newSamplePos.Y, out height); value += height * (fx1 * fy1); newSamplePos.X = samplePos.Y + 1; newSamplePos.Y = samplePos.Z; newFacePosition = MyCsgPrecomputedHelpres.GetFaceForTexcoord(ref newSamplePos, samplePos.X, m_header.Resolution); GetHeightFromBatch(newFacePosition, newSamplePos.X, newSamplePos.Y, out height); value += height * (fx * fy1); newSamplePos.X = samplePos.Y; newSamplePos.Y = samplePos.Z + 1; if (newSamplePos.Y < m_header.Resolution) { GetHeightFromBatch(samplePos.X, newSamplePos.X, newSamplePos.Y, out height); value += height * (fx1 * fy); newSamplePos.X = samplePos.Y + 1; newFacePosition = MyCsgPrecomputedHelpres.GetFaceForTexcoord(ref newSamplePos, samplePos.X, m_header.Resolution); GetHeightFromBatch(newFacePosition, newSamplePos.X, newSamplePos.Y, out height); value += height * (fx * fy); } } else { ushort height; GetHeightFromBatch(samplePos.X, samplePos.Y, samplePos.Z, out height); value = height; } if (MyFakes.ENABLE_PLANET_FROZEN_SEA) { return(Math.Max((value * m_maxHillHeight) / (float)m_header.MaxValue, MyCsgPrecomputedHelpres.FROZEN_OCEAN_LEVEL)); } return((value * m_maxHillHeight) / (float)m_header.MaxValue); }
private float SignedDistanceInternal(float lodVoxelSize, IMyModule macroModulator, IMyModule detailModulator, ref Vector3 localPosition, float distance) { if (distance > 0.0f) { float signedDistance = distance - m_averageRadius; Vector3I samplePos; Vector2 pos = Vector2.Zero; MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); float value = GetValueForPosition(ref samplePos, ref pos, true); return((signedDistance - value) / lodVoxelSize); } return(0.0f); }
public MyCsgShapePrecomputed(Vector3 translation, float averageRadius, string folderPath, float maxHillHeight) { m_maxHillHeight = maxHillHeight; m_file = new MemoryMappedFile[MyCsgPrecomputedHelpres.NUM_MAPS]; m_reader = new MemoryMappedViewAccessor[MyCsgPrecomputedHelpres.NUM_MAPS][]; for (int i = 0; i < MyCsgPrecomputedHelpres.NUM_MAPS; ++i) { string name = null; MyCsgPrecomputedHelpres.GetNameForFace(i, ref name); name = Path.Combine(folderPath, name + ".bin"); FileInfo fi = new FileInfo(name); long length = fi.Length; m_file[i] = MemoryMappedFile.CreateFromFile(name, FileMode.Open, null, 0, MemoryMappedFileAccess.Read); // read header separately m_headerLenght = 2 * sizeof(int) + 2 * sizeof(ushort); var headerReader = m_file[i].CreateViewAccessor(0, m_headerLenght, MemoryMappedFileAccess.Read); headerReader.Read(0, out m_header.MaxValue); headerReader.Read(sizeof(ushort), out m_header.BatchSize); headerReader.Read(2 * sizeof(ushort), out m_header.TypeSize); headerReader.Read(2 * sizeof(ushort) + sizeof(int), out m_header.Resolution); headerReader.Dispose(); var batchSectorsCount = m_header.Resolution / m_header.BatchSize; long batchLength = m_header.TypeSize * m_header.BatchSize * m_header.BatchSize; m_reader[i] = new MemoryMappedViewAccessor[batchSectorsCount * batchSectorsCount]; for (int j = 0; j < batchSectorsCount; ++j) { for (int k = 0; k < batchSectorsCount; ++k) { int batchIndex = j * batchSectorsCount + k; long offset = m_headerLenght + j * batchSectorsCount * batchLength + k * batchLength; long size = batchLength; m_reader[i][batchIndex] = m_file[i].CreateViewAccessor(offset, size, MemoryMappedFileAccess.Read); } } } m_batchLength = m_header.BatchSize * m_header.BatchSize * m_header.TypeSize; m_sectorCount = m_header.Resolution / m_header.BatchSize; m_averageRadius = averageRadius; m_translation = translation; m_innerRadius = averageRadius; m_outerRadius = averageRadius + m_maxHillHeight; }
internal override ContainmentType Contains(ref BoundingBox queryAabb, ref BoundingSphere querySphere, float lodVoxelSize) { ContainmentType outerContainment, innerContainment; BoundingSphere sphere = new BoundingSphere( m_translation, m_outerRadius + lodVoxelSize); sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) { return(ContainmentType.Disjoint); } sphere.Radius = m_innerRadius - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) { return(ContainmentType.Contains); } float minDistance = float.MaxValue; float maxDistance = -float.MaxValue; Vector3 localPosition = queryAabb.Min - m_translation; float distance = localPosition.LengthSquared(); if (distance < 0.01f) { return(ContainmentType.Intersects); } Vector3I samplePos; Vector2 pos = Vector2.Zero; MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); float value = GetValueForPosition(ref samplePos, ref pos, true); minDistance = MathHelper.Min(minDistance, value); maxDistance = MathHelper.Max(maxDistance, value); localPosition = queryAabb.Max - m_translation; distance = localPosition.LengthSquared(); if (distance < 0.01f) { return(ContainmentType.Intersects); } MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); value = GetValueForPosition(ref samplePos, ref pos, true); minDistance = MathHelper.Min(minDistance, value); maxDistance = MathHelper.Max(maxDistance, value); sphere.Radius = m_innerRadius + maxDistance + lodVoxelSize; sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) { return(ContainmentType.Disjoint); } sphere.Radius = m_innerRadius + minDistance - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) { return(ContainmentType.Contains); } return(ContainmentType.Intersects); }