/// <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; } float flattenOffset = 0; // This is a bit hacky. One fix could be that the VoxelMesher class has a flattenOffset property, but I'm not sure if that's a good idea either. if (voxelWorld.VoxelMesher is MarchingCubesMesher marchingCubesMesher) { flattenOffset = marchingCubesMesher.Isolevel; } int intRange = (int)math.ceil(deformRange); int size = 2 * intRange + 1; int3 queryPosition = (int3)(intersectionPoint - new int3(intRange)); BoundsInt worldSpaceQuery = new BoundsInt(queryPosition.ToVectorInt(), new Vector3Int(size, size, size)); voxelWorld.VoxelDataStore.SetVoxelDataCustom(worldSpaceQuery, (voxelDataWorldPosition, voxelData) => { float distance = math.distance(voxelDataWorldPosition, intersectionPoint); if (distance > deformRange) { return(voxelData); } float voxelDataChange = (math.dot(_flatteningNormal, voxelDataWorldPosition) - math.dot(_flatteningNormal, _flatteningOrigin)) / deformRange; return((byte)math.clamp(((voxelDataChange * 0.5f + voxelData / 255f - flattenOffset) * 0.8f + flattenOffset) * 255, 0, 255)); }); }
public void Line_At_1_0_0_Plane_At_0_0_0_Custom_Angle_Should_Be_1_Negative2_0() { float3 planeOrigin = new float3(0, 0, 0); float3 planeNormal = math.normalize(new float3(1, 0.5f, 0)); float3 lineOrigin = new float3(1, 0, 0); float3 lineDirection = new float3(0, -1, 0); PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(planeOrigin, planeNormal, lineOrigin, lineDirection, out float3 intersectionPoint); Assert.AreEqual(new float3(1, -2, 0), intersectionPoint); }
public void Line_Above_Directly_Down_Result_Should_Be_OneHit() { float3 planeOrigin = new float3(0, 0, 0); float3 planeNormal = math.normalize(new float3(0, 1, 0)); float3 lineOrigin = new float3(0, 10, 0); float3 lineDirection = new float3(0, -1, 0); PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(planeOrigin, planeNormal, lineOrigin, lineDirection, out float3 intersectionPoint); Assert.AreEqual(PlaneLineIntersectionResult.OneHit, result); }
public void Line_Parallel_To_Plane_Inside_Result_Should_Be_ParallelInsidePlane() { float3 planeOrigin = new float3(0, 4, 0); float3 planeNormal = math.normalize(new float3(0, 1, 0)); float3 lineOrigin = new float3(0, 4, 0); float3 lineDirection = new float3(1, 0, 0); PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(planeOrigin, planeNormal, lineOrigin, lineDirection, out float3 intersectionPoint); Assert.AreEqual(PlaneLineIntersectionResult.ParallelInsidePlane, result); }
public void Line_At_10_4_5_Directly_Down_Should_Hit_10_0_5() { float3 planeOrigin = new float3(0, 0, 0); float3 planeNormal = math.normalize(new float3(0, 1, 0)); float3 lineOrigin = new float3(10, 4, 5); float3 lineDirection = new float3(0, -1, 0); PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(planeOrigin, planeNormal, lineOrigin, lineDirection, out float3 intersectionPoint); Assert.AreEqual(new float3(10, 0, 5), intersectionPoint); }
/// <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); } } } } }
private static void TestPlaneLineIntersectionResult(float3 planeOrigin, float3 planeNormal, float3 lineOrigin, float3 lineDirection, PlaneLineIntersectionResult expected) { PlaneLineIntersectionResult result = IntersectionUtilities.PlaneLineIntersection(planeOrigin, math.normalize(planeNormal), lineOrigin, lineDirection, out _); Assert.AreEqual(expected, result); }
private static void TestPlaneLineIntersectionPoint(float3 planeOrigin, float3 planeNormal, float3 lineOrigin, float3 lineDirection, float3 expected) { _ = IntersectionUtilities.PlaneLineIntersection(planeOrigin, planeNormal, lineOrigin, lineDirection, out float3 intersectionPoint); Assert.AreEqual(expected, intersectionPoint); }