/// <summary> /// Deforms the terrain in a spherical region around the point /// </summary> /// <param name="point">The point to modify the terrain around</param> /// <param name="addTerrain">Should terrain be added or removed</param> /// <param name="deformSpeed">How fast the terrain should be deformed</param> /// <param name="range">How far the deformation can reach</param> private void EditTerrain(Vector3 point, bool addTerrain, float deformSpeed, float range) { int buildModifier = addTerrain ? 1 : -1; int hitX = Mathf.RoundToInt(point.x); int hitY = Mathf.RoundToInt(point.y); int hitZ = Mathf.RoundToInt(point.z); int intRange = Mathf.CeilToInt(range); for (int x = -intRange; x <= intRange; x++) { for (int y = -intRange; y <= intRange; y++) { for (int z = -intRange; z <= intRange; z++) { int offsetX = hitX - x; int offsetY = hitY - y; int offsetZ = hitZ - z; int3 offsetPoint = new int3(offsetX, offsetY, offsetZ); float distance = math.distance(offsetPoint, point); if (distance > range) { continue; } float modificationAmount = deformSpeed / distance * buildModifier; if (voxelDataStore.TryGetVoxelData(offsetPoint, out float oldVoxelData)) { float newVoxelData = oldVoxelData - modificationAmount; voxelDataStore.SetVoxelData(newVoxelData, offsetPoint); } } } } }
/// <summary> /// Get a point on the flattening plane and flatten the terrain around it /// </summary> private void FlattenTerrain() { PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(_flatteningOrigin, _flatteningNormal, playerCamera.position, playerCamera.forward, out float3 intersectionPoint); if (result != PlaneLineIntersectionResult.OneHit) { return; } int intRange = (int)math.ceil(deformRange); for (int x = -intRange; x <= intRange; x++) { for (int y = -intRange; y <= intRange; y++) { for (int z = -intRange; z <= intRange; z++) { int3 localPosition = new int3(x, y, z); float3 offsetPoint = intersectionPoint + localPosition; float distance = math.distance(offsetPoint, intersectionPoint); if (distance > deformRange) { continue; } int3 voxelDataWorldPosition = (int3)offsetPoint; if (voxelDataStore.TryGetVoxelData(voxelDataWorldPosition, out float oldVoxelData)) { float voxelDataChange = (math.dot(_flatteningNormal, voxelDataWorldPosition) - math.dot(_flatteningNormal, _flatteningOrigin)) / deformRange; voxelDataStore.SetVoxelData((voxelDataChange * 0.5f + oldVoxelData) * 0.8f, voxelDataWorldPosition); } } } } }