public void CollisionCheck(){ IEnumerator<Collider> prevCols = prevCollisions.Keys.GetEnumerator(); while (prevCols.MoveNext ()) { Collider c = prevCols.Current; if (collisions.ContainsKey (c)) { continue; } if (Mathf.Abs((transform.position - c.transform.position).sqrMagnitude - ( ((Transform)transform.previous).position - ((Transform)c.transform.previous).position).sqrMagnitude) <= Util.thin ){ Collision selfOldCollision = this.prevCollisions [c]; Collision selfCollision = new Collision ( this, c, new Vector2[]{selfOldCollision.contactPoints[selfOldCollision.contactPoints.Length-1]}, new Vector2[]{Vector2.zero}, new Vector2[]{selfOldCollision.normals[selfOldCollision.normals.Length-1]}, new float[]{0} ); Collision otherOldCollision = c.prevCollisions [this]; Collision otherCollision = new Collision ( c, this, new Vector2[]{otherOldCollision.contactPoints[otherOldCollision.contactPoints.Length-1]}, new Vector2[]{Vector2.zero}, new Vector2[]{otherOldCollision.normals[otherOldCollision.normals.Length-1]}, new float[]{0} ); this.AddCollision (selfCollision); c.AddCollision (otherCollision); } } }
public static UnityEngine.Vector3Int RotateBySector(this UnityEngine.Vector3Int vecUp, FLOAT3 dir) { var p = vecUp; var x = Mathf.Abs(dir.x); var z = Mathf.Abs(dir.z); if (dir.x >= 0f && x >= z) { // right vecUp = vecUp.Rotate90(); } else if (dir.z >= 0f && z >= x) { // up } else if (dir.z <= 0f && z >= x) { // down vecUp = vecUp.Rotate90(); vecUp = vecUp.Rotate90(); } else if (dir.x <= 0f && x >= z) { // left vecUp = vecUp.Rotate90(); vecUp = vecUp.Rotate90(); vecUp = vecUp.Rotate90(); } return(vecUp); }
public static Vector2 MaxRequirement(Vector2 a, Vector2 b) { float x = Mathf.Abs(a.x) > Mathf.Abs(b.x) ? a.x : b.x; float y = Mathf.Abs(a.y) > Mathf.Abs(b.y) ? a.y : b.y; return(new Vector2(x, y)); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } stepHeight = Mathf.Max(kMinStepHeight, stepHeight); innerDiameter = Mathf.Min(outerDiameter - kMinStairsDepth, innerDiameter); innerDiameter = Mathf.Max(kMinInnerDiameter, innerDiameter); outerDiameter = Mathf.Max(innerDiameter + kMinStairsDepth, outerDiameter); outerDiameter = Mathf.Max(kMinOuterDiameter, outerDiameter); height = Mathf.Max(stepHeight, Mathf.Abs(height)) * (height < 0 ? -1 : 1); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); rotation = Mathf.Max(kMinRotation, Mathf.Abs(rotation)) * (rotation < 0 ? -1 : 1); innerSegments = Mathf.Max(kMinSegments, innerSegments); outerSegments = Mathf.Max(kMinSegments, outerSegments); surfaceDefinition.EnsureSize(8); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } if (surfaceDefinition.EnsureSize((int)SurfaceSides.TotalSides)) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceDefinition.surfaces[(int)SurfaceSides.Top].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Bottom].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Left].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Right].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Forward].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Back].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Tread].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultTreadMaterial, defaultPhysicsMaterial); surfaceDefinition.surfaces[(int)SurfaceSides.Step].brushMaterial = ChiselBrushMaterial.CreateInstance(CSGMaterialManager.DefaultStepMaterial, defaultPhysicsMaterial); for (int i = 0; i < surfaceDefinition.surfaces.Length; i++) { if (surfaceDefinition.surfaces[i].brushMaterial == null) { surfaceDefinition.surfaces[i].brushMaterial = ChiselBrushMaterial.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } } stepHeight = Mathf.Max(kMinStepHeight, stepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth)); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); width = Mathf.Max(kMinWidth, Mathf.Abs(width)) * (width < 0 ? -1 : 1); depth = Mathf.Max(stepDepth, Mathf.Abs(depth)) * (depth < 0 ? -1 : 1); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); sideDepth = Mathf.Max(0, sideDepth); sideWidth = Mathf.Max(kMinSideWidth, sideWidth); sideHeight = Mathf.Max(0, sideHeight); var absHeight = Mathf.Max(stepHeight, Mathf.Abs(height)); var maxPlateauHeight = absHeight - stepHeight; plateauHeight = Mathf.Clamp(plateauHeight, 0, maxPlateauHeight); var totalSteps = Mathf.Max(1, Mathf.FloorToInt((absHeight - plateauHeight) / stepHeight)); var totalStepHeight = totalSteps * stepHeight; plateauHeight = Mathf.Max(0, absHeight - totalStepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth) / totalSteps); }
public void Validate() { diameterXYZ.x = Mathf.Max(kMinDiameter, Mathf.Abs(diameterXYZ.x)); diameterXYZ.y = Mathf.Max(0, Mathf.Abs(diameterXYZ.y)) * (diameterXYZ.y < 0 ? -1 : 1); diameterXYZ.z = Mathf.Max(kMinDiameter, Mathf.Abs(diameterXYZ.z)); horizontalSegments = Mathf.Max(horizontalSegments, 3); verticalSegments = Mathf.Max(verticalSegments, 1); if (surfaceAssets == null || surfaceAssets.Length != 6) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[6] { CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial), CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial), CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial), CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial), CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial), CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial) }; } if (surfaceDescriptions == null || surfaceDescriptions.Length != 6) { // TODO: make this independent on plane position somehow var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[6] { new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 }, new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 }, new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 }, new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 }, new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 }, new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 } }; } }
public void Validate() { stepHeight = Mathf.Max(kMinStepHeight, stepHeight); innerDiameter = Mathf.Min(outerDiameter - kMinStairsDepth, innerDiameter); innerDiameter = Mathf.Max(kMinInnerDiameter, innerDiameter); outerDiameter = Mathf.Max(innerDiameter + kMinStairsDepth, outerDiameter); outerDiameter = Mathf.Max(kMinOuterDiameter, outerDiameter); height = Mathf.Max(stepHeight, Mathf.Abs(height)) * (height < 0 ? -1 : 1); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); rotation = Mathf.Max(kMinRotation, Mathf.Abs(rotation)) * (rotation < 0 ? -1 : 1); innerSegments = Mathf.Max(kMinSegments, innerSegments); outerSegments = Mathf.Max(kMinSegments, outerSegments); if (surfaceAssets == null || surfaceAssets.Length != 6) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[6]; for (int i = 0; i < 6; i++) // Note: sides share same material { surfaceAssets[i] = CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } if (surfaceDescriptions == null || surfaceDescriptions.Length != 6) { var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[6]; for (int i = 0; i < 6; i++) { surfaceDescriptions[i] = new SurfaceDescription { surfaceFlags = surfaceFlags, UV0 = UVMatrix.centered, smoothingGroup = bottomSmoothingGroup }; } } else { for (int i = 0; i < 6; i++) { surfaceDescriptions[i].smoothingGroup = bottomSmoothingGroup; } } }
public bool Equals(CSGPlane other) { if (System.Object.ReferenceEquals(this, other)) { return(true); } if (System.Object.ReferenceEquals(other, null)) { return(false); } return(Mathf.Abs(this.Distance(other.pointOnPlane)) <= MathConstants.DistanceEpsilon && Mathf.Abs(other.Distance(this.pointOnPlane)) <= MathConstants.DistanceEpsilon && Mathf.Abs(a - other.a) <= MathConstants.NormalEpsilon && Mathf.Abs(b - other.b) <= MathConstants.NormalEpsilon && Mathf.Abs(c - other.c) <= MathConstants.NormalEpsilon); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } diameterXYZ.x = Mathf.Max(kMinDiameter, Mathf.Abs(diameterXYZ.x)); diameterXYZ.y = Mathf.Max(0, Mathf.Abs(diameterXYZ.y)) * (diameterXYZ.y < 0 ? -1 : 1); diameterXYZ.z = Mathf.Max(kMinDiameter, Mathf.Abs(diameterXYZ.z)); horizontalSegments = Mathf.Max(horizontalSegments, 3); verticalSegments = Mathf.Max(verticalSegments, 1); surfaceDefinition.EnsureSize(6); }
public static bool IsValid(UnityEngine.Vector3 min, UnityEngine.Vector3 max) { const float kMinSize = 0.0001f; if (Mathf.Abs(max.x - min.x) < kMinSize || Mathf.Abs(max.y - min.y) < kMinSize || Mathf.Abs(max.z - min.z) < kMinSize || float.IsInfinity(min.x) || float.IsInfinity(min.y) || float.IsInfinity(min.z) || float.IsInfinity(max.x) || float.IsInfinity(max.y) || float.IsInfinity(max.z) || float.IsNaN(min.x) || float.IsNaN(min.y) || float.IsNaN(min.z) || float.IsNaN(max.x) || float.IsNaN(max.y) || float.IsNaN(max.z)) { return(false); } return(true); }
public void Validate() { topLength = Mathf.Max(topLength, 0); bottomLength = Mathf.Max(bottomLength, 0); length = Mathf.Max(Mathf.Abs(length), (haveRoundedTop ? topLength : 0) + (haveRoundedBottom ? bottomLength : 0)); length = Mathf.Max(Mathf.Abs(length), kMinLength); height = Mathf.Max(Mathf.Abs(height), kMinHeight); diameter = Mathf.Max(Mathf.Abs(diameter), kMinDiameter); topSides = Mathf.Max(topSides, 1); bottomSides = Mathf.Max(bottomSides, 1); var sides = 2 + Mathf.Max(topSides, 1) + Mathf.Max(bottomSides, 1); int kMinSurfaceAssets = 2 + sides; if (surfaceAssets == null || surfaceAssets.Length != kMinSurfaceAssets) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[kMinSurfaceAssets]; for (int a = 0; a < kMinSurfaceAssets; a++) { surfaceAssets[a] = CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } int kMinSurfaceDescriptions = 2 + sides; if (surfaceDescriptions == null || surfaceDescriptions.Length != kMinSurfaceDescriptions) { // TODO: make this independent on plane position somehow var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[kMinSurfaceDescriptions]; for (int s = 0; s < kMinSurfaceDescriptions; s++) { surfaceDescriptions[s] = new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 } } ; } } }
public static bool operator !=(CSGPlane left, CSGPlane right) { if (System.Object.ReferenceEquals(left, right)) { return(false); } if (System.Object.ReferenceEquals(left, null) || System.Object.ReferenceEquals(right, null)) { return(true); } return(Mathf.Abs(left.Distance(right.pointOnPlane)) > MathConstants.DistanceEpsilon && Mathf.Abs(right.Distance(left.pointOnPlane)) > MathConstants.DistanceEpsilon && Mathf.Abs(left.a - right.a) > MathConstants.NormalEpsilon || Mathf.Abs(left.b - right.b) > MathConstants.NormalEpsilon || Mathf.Abs(left.c - right.c) > MathConstants.NormalEpsilon); }
public void Validate() { topHeight = Mathf.Max(topHeight, 0); bottomHeight = Mathf.Max(bottomHeight, 0); height = Mathf.Max(topHeight + bottomHeight, Mathf.Abs(height)) * (height < 0 ? -1 : 1); diameterX = Mathf.Max(Mathf.Abs(diameterX), kMinDiameter); diameterZ = Mathf.Max(Mathf.Abs(diameterZ), kMinDiameter); topSegments = Mathf.Max(topSegments, 0); bottomSegments = Mathf.Max(bottomSegments, 0); sides = Mathf.Max(sides, 3); var minSurfaceAssets = 2 + sides; if (surfaceAssets == null || surfaceAssets.Length != minSurfaceAssets) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[minSurfaceAssets]; for (int a = 0; a < minSurfaceAssets; a++) { surfaceAssets[a] = CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } var minSurfaceDescriptions = 2 + sides; if (surfaceDescriptions == null || surfaceDescriptions.Length != minSurfaceDescriptions) { // TODO: make this independent on plane position somehow var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[minSurfaceDescriptions]; for (int s = 0; s < minSurfaceDescriptions; s++) { surfaceDescriptions[s] = new SurfaceDescription { UV0 = UVMatrix.centered, surfaceFlags = surfaceFlags, smoothingGroup = 0 } } ; } } }
private static bool ProjectOverlapTest(Vector3 axis, Vector3[] srcPoints, Vector3[] dstPoints, out float overlap) { float srcMin = float.MaxValue; float dstMin = float.MaxValue; float srcMax = float.MinValue; float dstMax = float.MinValue; for (int i = 0; i < srcPoints.Length; i++) { var p = Vector3.Dot(axis, srcPoints[i]); if (p < srcMin) { srcMin = p; } if (p > srcMax) { srcMax = p; } } for (int i = 0; i < dstPoints.Length; i++) { var p = Vector3.Dot(axis, dstPoints[i]); if (p < dstMin) { dstMin = p; } if (p > dstMax) { dstMax = p; } } if (srcMax < dstMin || srcMin > dstMax) { overlap = 0; return(false); } overlap = Mathf.Min(srcMax, dstMax) - Mathf.Max(srcMin, dstMin); if ((srcMax > dstMax && srcMin < dstMin) || (srcMax < dstMax && srcMin > dstMin)) { var min = Mathf.Abs(srcMin - dstMin); var max = Mathf.Abs(srcMax - dstMax); overlap += Mathf.Min(min, max); } return(true); }
static float ApproximateEdgeDelta(float gx, float gy, float a) { // (gx, gy) can be either the local pixel gradient or the direction to the pixel if (gx == 0f || gy == 0f) { // linear function is correct if both gx and gy are zero // and still fair if only one of them is zero return(0.5f - a); } // normalize (gx, gy) float length = (float)Math.Sqrt(gx * gx + gy * gy); gx = gx / length; gy = gy / length; // reduce symmetrical equation to first octant only // gx >= 0, gy >= 0, gx >= gy gx = Math.Abs(gx); gy = Math.Abs(gy); if (gx < gy) { float temp = gx; gx = gy; gy = temp; } // compute delta float a1 = 0.5f * gy / gx; if (a < a1) { // 0 <= a < a1 return(0.5f * (gx + gy) - (float)Math.Sqrt(2f * gx * gy * a)); } if (a < (1f - a1)) { // a1 <= a <= 1 - a1 return((0.5f - a) * gx); } // 1-a1 < a <= 1 return(-0.5f * (gx + gy) + (float)Math.Sqrt(2f * gx * gy * (1f - a))); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } topHeight = Mathf.Max(topHeight, 0); bottomHeight = Mathf.Max(bottomHeight, 0); height = Mathf.Max(topHeight + bottomHeight, Mathf.Abs(height)) * (height < 0 ? -1 : 1); diameterX = Mathf.Max(Mathf.Abs(diameterX), kMinDiameter); diameterZ = Mathf.Max(Mathf.Abs(diameterZ), kMinDiameter); topSegments = Mathf.Max(topSegments, 0); bottomSegments = Mathf.Max(bottomSegments, 0); sides = Mathf.Max(sides, 3); surfaceDefinition.EnsureSize(2 + sides); }
public static bool Intersect(CubeXCollider src, CubeXCollider dst, out XContact?contact) { Vector3 normal; float penetration; if (!SATTest(src, dst, out normal, out penetration)) { contact = null; return(false); } var srcExtents = src.Size * 0.5f; var dstExtents = dst.Size * 0.5f; var srcMinY = src.Position.y - srcExtents.y; var srcMaxY = src.Position.y + srcExtents.y; var dstMinY = dst.Position.y - dstExtents.y; var dstMaxY = dst.Position.y + dstExtents.y; var overlapY = Mathf.Min(srcMaxY, dstMaxY) - Mathf.Max(srcMinY, dstMinY); if ((srcMaxY > dstMaxY && srcMinY < dstMinY) || (srcMaxY < dstMaxY && srcMinY > dstMinY)) { var min = Mathf.Abs(srcMinY - dstMinY); var max = Mathf.Abs(srcMaxY - dstMaxY); overlapY += Mathf.Min(min, max); } if (overlapY < penetration) { penetration = overlapY; normal = Vector3.up; } if (Vector3.Dot(normal, dst.Position - src.Position) < 0) { normal = -normal; } contact = new XContact(src, dst, normal, penetration); return(true); }
static void PostProcess(float maxDistance) { // adjust distances near edges based on the local edge gradient for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Pixel p = pixels[x, y]; if ((p.dX == 0 && p.dY == 0) || p.distance >= maxDistance) { // ignore edge, inside, and beyond max distance continue; } float dX = p.dX, dY = p.dY; Pixel closest = pixels[x - p.dX, y - p.dY]; Vector2 g = closest.gradient; if (g.x == 0f && g.y == 0f) { // ignore unknown gradients (inside) continue; } // compute hit point offset on gradient inside pixel float df = ApproximateEdgeDelta(g.x, g.y, closest.alpha); float t = dY * g.x - dX * g.y; float u = -df * g.x + t * g.y; float v = -df * g.y - t * g.x; // use hit point to compute distance if (Math.Abs(u) <= 0.5f && Math.Abs(v) <= 0.5f) { p.distance = (float)Math.Sqrt((dX + u) * (dX + u) + (dY + v) * (dY + v)); } } } }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } topLength = Mathf.Max(topLength, 0); bottomLength = Mathf.Max(bottomLength, 0); length = Mathf.Max(Mathf.Abs(length), (haveRoundedTop ? topLength : 0) + (haveRoundedBottom ? bottomLength : 0)); length = Mathf.Max(Mathf.Abs(length), kMinLength); height = Mathf.Max(Mathf.Abs(height), kMinHeight); diameter = Mathf.Max(Mathf.Abs(diameter), kMinDiameter); topSides = Mathf.Max(topSides, 1); bottomSides = Mathf.Max(bottomSides, 1); var sides = 2 + Mathf.Max(topSides, 1) + Mathf.Max(bottomSides, 1); surfaceDefinition.EnsureSize(2 + sides); }
public void Validate() { if (surfaceDefinition == null) { surfaceDefinition = new ChiselSurfaceDefinition(); } topDiameterX = Mathf.Abs(topDiameterX); topDiameterZ = Mathf.Abs(topDiameterZ); bottomDiameterX = Mathf.Abs(bottomDiameterX); bottomDiameterZ = Mathf.Abs(bottomDiameterZ); sides = Mathf.Max(3, sides); if (surfaceDefinition.EnsureSize(2 + sides)) { // Top plane surfaceDefinition.surfaces[0].surfaceDescription.UV0 = UVMatrix.centered; // Bottom plane surfaceDefinition.surfaces[1].surfaceDescription.UV0 = UVMatrix.centered; float radius = topDiameterX * 0.5f; float angle = (360.0f / sides); float sideLength = (2 * Mathf.Sin((angle / 2.0f) * Mathf.Deg2Rad)) * radius; // Side planes for (int i = 2; i < 2 + sides; i++) { var uv0 = UVMatrix.identity; uv0.U.w = ((i - 2) + 0.5f) * sideLength; // TODO: align with bottom //uv0.V.w = 0.5f; surfaceDefinition.surfaces[i].surfaceDescription.UV0 = uv0; surfaceDefinition.surfaces[i].surfaceDescription.smoothingGroup = smoothingGroup; } } }
private IEnumerator Tick() { while (true) { var tankMovementSoundEntityViews = entityViewsDB.QueryEntityViews <TankMovementSoundEntityView>(); if (tankMovementSoundEntityViews.Count > 0) { for (int i = 0; i < tankMovementSoundEntityViews.Count; i++) { IAudioSourceComponent audioSourceComponent = tankMovementSoundEntityViews[i].AudioSourceComponent; ITankMovementSoundsComponent soundComponent = tankMovementSoundEntityViews[i].TankMovementSoundsComponent; ITankInputComponent inputComponent = tankMovementSoundEntityViews[i].TankInputComponent; if (Mathf.Abs(inputComponent.Input.z) < 0.1f && Mathf.Abs(inputComponent.Input.x) < 0.1f) { if (audioSourceComponent.Clip == soundComponent.EngineDrivingAudioClip) { audioSourceComponent.Clip = soundComponent.IdleAudioClip; audioSourceComponent.Pitch = Random.Range(1 - 0.1f, 1 + 0.1f); audioSourceComponent.Play(); } } else { if (audioSourceComponent.Clip == soundComponent.IdleAudioClip) { // ... change the clip to driving and play. audioSourceComponent.Clip = soundComponent.EngineDrivingAudioClip; audioSourceComponent.Pitch = Random.Range(1 - 0.1f, 1 + 0.1f); audioSourceComponent.Play(); } } } } yield return(null); } }
public static bool Intersect(CylinderXCollider src, SphereXCollider dst, out XContact?contact) { var n = dst.Position - src.Position; Vector3 closest = n; var extents = src.bounds.Extents; closest.x = Mathf.Clamp(closest.x, -extents.x, extents.x); closest.y = Mathf.Clamp(closest.y, -extents.y, extents.y); closest.z = Mathf.Clamp(closest.z, -extents.z, extents.z); var v = new Vector2(closest.x, closest.z); if (v.sqrMagnitude > src.Radius * src.Radius) { v = v.normalized * src.Radius; closest.x = v.x; closest.z = v.y; } bool inside = false; if (n == closest) { inside = true; // 往上下移动的最短距离 var dist1 = extents.y - Mathf.Abs(closest.y); // 往水平四周移动的最短距离 var dist2 = src.Radius - v.magnitude; if (dist1 < dist2) { closest.y = closest.y > 0 ? extents.y : -extents.y; } else { v = v.normalized * src.Radius; closest.x = v.x; closest.z = v.y; } } var dir = n - closest; var sqrDist = dir.sqrMagnitude; var space = dst.Radius; var sqrSpace = space * space; if (sqrDist < sqrSpace || inside) { var dist = Mathf.Sqrt(sqrDist); var normal = dir.normalized; var penetration = space - dist; if (inside) { normal = -normal; penetration = space + dist; } if (normal == Vector3.zero) { normal = Vector3.up; } contact = new XContact(src, dst, normal, penetration); return(true); } contact = null; return(false); }
public static bool Intersect(CubeXCollider src, CylinderXCollider dst, out XContact?contact) { var invP = Quaternion.Inverse(src.Quaternion) * (dst.Position - src.Position); Vector3 n = Vector3.zero; n.x = invP.x; n.z = invP.z; var extents = src.Size * 0.5f; var halfHa = extents.y; var topA = halfHa; var bottomA = -halfHa; var halfHb = dst.Height * 0.5f; var topB = invP.y + halfHb; var bottomB = invP.y - halfHb; var space = dst.Radius; var sqrSpace = space * space; // 相撞时,俯视图下的圆和矩形必然相交 var closest = n; closest.x = Mathf.Clamp(closest.x, -extents.x, extents.x); closest.z = Mathf.Clamp(closest.z, -extents.z, extents.z); if ((n - closest).sqrMagnitude > sqrSpace) { contact = null; return(false); } // 处理相交的情况 Vector3 normal; float penetration; float verticalP = float.PositiveInfinity; float horizontalP; var inside = false; if (n == closest) { inside = true; var disX = extents.x - Mathf.Abs(n.x); var disZ = extents.z - Mathf.Abs(n.z); //找到最近的一个面 if (disX < disZ) { // 沿X轴 if (n.x > 0) { closest.x = extents.x; } else { closest.x = -extents.x; } } else { // 沿Z轴 if (n.z > 0) { closest.z = extents.z; } else { closest.z = -extents.z; } } horizontalP = space + (n - closest).magnitude; } else { horizontalP = space - (n - closest).magnitude; } if (Mathf.Sign(topA - topB) != Mathf.Sign(bottomB - bottomA)) { // 斜向相撞 if (topB > topA) { verticalP = topA - bottomB; } else { verticalP = topB - bottomA; } } if (horizontalP < verticalP) { normal = (src.Quaternion * (n - closest)).normalized; if (inside) { normal = -normal; } penetration = horizontalP; } else { normal = topB > topA ? Vector3.up : Vector3.down; penetration = verticalP; } if (normal == Vector3.zero) { normal = Vector3.up; } contact = new XContact(src, dst, normal, penetration); return(true); }
public static bool Intersect(CubeXCollider src, SphereXCollider dst, out XContact?contact) { // 反向旋转sphere的位置,使得可以在cube的坐标系下进行碰撞判断 var extents = src.Size * 0.5f; var invQ = Quaternion.Inverse(src.Quaternion); var invP = invQ * (dst.Position - src.Position); // 以下所有操作都是在cube的坐标系下,随后的实际方向需要进行坐标系转换 var n = invP; var closest = n; closest.x = Mathf.Clamp(closest.x, -extents.x, extents.x); closest.y = Mathf.Clamp(closest.y, -extents.y, extents.y); closest.z = Mathf.Clamp(closest.z, -extents.z, extents.z); var inside = false; if (n == closest) { inside = true; var disX = extents.x - Mathf.Abs(n.x); var disY = extents.y - Mathf.Abs(n.y); var disZ = extents.z - Mathf.Abs(n.z); //找到最近的一个面 if (disX < disY && disX < disZ) { // 沿X轴 if (n.x > 0) { closest.x = extents.x; } else { closest.x = -extents.x; } } else if (disY < disX && disY < disZ) { // 沿Y轴 if (n.y > 0) { closest.y = extents.y; } else { closest.y = -extents.y; } } else { // 沿Z轴 if (n.z > 0) { closest.z = extents.z; } else { closest.z = -extents.z; } } } var dir = n - closest; var sqrDist = dir.sqrMagnitude; var space = dst.Radius; var sqrSpace = space * space; if (sqrDist < sqrSpace || inside) { var dist = Mathf.Sqrt(sqrDist); var normal = (src.Quaternion * dir).normalized; var penetration = space - dist; if (inside) { normal = -normal; penetration = space + dist; } if (normal == Vector3.zero) { normal = Vector3.up; } contact = new XContact(src, dst, normal, penetration); return(true); } contact = null; return(false); }
public void OnEdit(IChiselHandles handles) { // Store our allocated handles in generatorState to avoid reallocating them every frame var cylinderHandles = handles.generatorState as CylinderHandles; if (cylinderHandles == null) { cylinderHandles = new CylinderHandles(); cylinderHandles.Init(handles, this); handles.generatorState = cylinderHandles; } cylinderHandles.Update(handles, this); // Render vertical lines at the horizon of the cylinder handles.DoRenderHandles(new[] { cylinderHandles.verticalHandle1, cylinderHandles.verticalHandle2 }); // Move the cylinder top/bottom up/down var prevModified = handles.modified; { handles.DoSlider1DHandle(ref cylinderHandles.bottomPoint, -cylinderHandles.normal, cylinderHandles.bottomHandles); var haveFocus = handles.lastHandleHadFocus; handles.DoSlider1DHandle(ref cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topHandles); haveFocus = haveFocus || handles.lastHandleHadFocus; if (haveFocus) { handles.RenderDistanceMeasurement(cylinderHandles.topPoint, cylinderHandles.bottomPoint, Mathf.Abs(height)); } } if (prevModified != handles.modified) { cylinderHandles.topY = Vector3.Dot(Vector3.up, cylinderHandles.topPoint); cylinderHandles.bottomY = Vector3.Dot(Vector3.up, cylinderHandles.bottomPoint); height = cylinderHandles.topY - cylinderHandles.bottomY; bottomOffset = cylinderHandles.bottomY; } // Resize the top/bottom circle by grabbing and dragging it prevModified = handles.modified; { // Make the bottom circle draggable DraggableRadius(handles, ref bottomDiameterX, ref bottomDiameterZ, cylinderHandles.bottomPoint, -cylinderHandles.normal, cylinderHandles.bottomXVector, cylinderHandles.bottomZVector, cylinderHandles.bottomRadiusHandles, this.isEllipsoid); // If we're a Cylinder, the top circle actually changes the bottom circle too if (type == CylinderShapeType.Cylinder) { DraggableRadius(handles, ref bottomDiameterX, ref bottomDiameterZ, cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topXVector, cylinderHandles.topZVector, cylinderHandles.topRadiusHandles, this.isEllipsoid); } else // If we're a Conical Frustum, the top circle can be resized independently from the bottom circle if (type == CylinderShapeType.ConicalFrustum) { DraggableRadius(handles, ref topDiameterX, ref topDiameterZ, cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topXVector, cylinderHandles.topZVector, cylinderHandles.topRadiusHandles, this.isEllipsoid); } // else; If we're a Cone, we ignore the top circle } if (prevModified != handles.modified) { // Ensure that when our shape is circular and we modify it, that when we convert back to an ellipsoid, it'll still be circular if (!this.isEllipsoid) { topDiameterZ = topDiameterX; bottomDiameterZ = bottomDiameterX; } } }
public static FLOAT2 Abs(FLOAT2 v) { return(new FLOAT2(Mathf.Abs(v.x), Mathf.Abs(v.y))); }
public void Validate() { if (surfaceAssets == null || surfaceDescriptions.Length != (int)SurfaceSides.TotalSides) { var defaultRenderMaterial = CSGMaterialManager.DefaultWallMaterial; var defaultPhysicsMaterial = CSGMaterialManager.DefaultPhysicsMaterial; surfaceAssets = new CSGSurfaceAsset[(int)SurfaceSides.TotalSides]; surfaceAssets[(int)SurfaceSides.Top] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Bottom] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultFloorMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Left] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Right] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Forward] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Back] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultWallMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Tread] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultTreadMaterial, defaultPhysicsMaterial); surfaceAssets[(int)SurfaceSides.Step] = CSGSurfaceAsset.CreateInstance(CSGMaterialManager.DefaultStepMaterial, defaultPhysicsMaterial); for (int i = 0; i < surfaceAssets.Length; i++) { if (surfaceAssets[i] == null) { surfaceAssets[i] = CSGSurfaceAsset.CreateInstance(defaultRenderMaterial, defaultPhysicsMaterial); } } topSurface = surfaceAssets[(int)SurfaceSides.Top]; bottomSurface = surfaceAssets[(int)SurfaceSides.Bottom]; leftSurface = surfaceAssets[(int)SurfaceSides.Left]; rightSurface = surfaceAssets[(int)SurfaceSides.Right]; forwardSurface = surfaceAssets[(int)SurfaceSides.Forward]; backSurface = surfaceAssets[(int)SurfaceSides.Back]; treadSurface = surfaceAssets[(int)SurfaceSides.Tread]; stepSurface = surfaceAssets[(int)SurfaceSides.Step]; } if (surfaceDescriptions == null || surfaceDescriptions.Length != 6) { var surfaceFlags = CSGDefaults.SurfaceFlags; surfaceDescriptions = new SurfaceDescription[6]; for (int i = 0; i < 6; i++) { surfaceDescriptions[i] = new SurfaceDescription { surfaceFlags = surfaceFlags, UV0 = UVMatrix.centered }; } } stepHeight = Mathf.Max(kMinStepHeight, stepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth)); treadHeight = Mathf.Max(0, treadHeight); nosingDepth = Mathf.Max(0, nosingDepth); nosingWidth = Mathf.Max(0, nosingWidth); width = Mathf.Max(kMinWidth, Mathf.Abs(width)) * (width < 0 ? -1 : 1); depth = Mathf.Max(stepDepth, Mathf.Abs(depth)) * (depth < 0 ? -1 : 1); riserDepth = Mathf.Max(kMinRiserDepth, riserDepth); sideDepth = Mathf.Max(0, sideDepth); sideWidth = Mathf.Max(kMinSideWidth, sideWidth); sideHeight = Mathf.Max(0, sideHeight); var absHeight = Mathf.Max(stepHeight, Mathf.Abs(height)); var maxPlateauHeight = absHeight - stepHeight; plateauHeight = Mathf.Clamp(plateauHeight, 0, maxPlateauHeight); var totalSteps = Mathf.Max(1, Mathf.FloorToInt((absHeight - plateauHeight) / stepHeight)); var totalStepHeight = totalSteps * stepHeight; plateauHeight = Mathf.Max(0, absHeight - totalStepHeight); stepDepth = Mathf.Clamp(stepDepth, kMinStepDepth, Mathf.Abs(depth) / totalSteps); }
// // TODO: code below needs to be cleaned up & simplified // public void OnEdit(IChiselHandles handles) { var newDefinition = this; { var stepDepthOffset = this.StepDepthOffset; var stepHeight = this.stepHeight; var stepCount = this.StepCount; var bounds = this.bounds; var steps = handles.moveSnappingSteps; steps.y = stepHeight; if (handles.DoBoundsHandle(ref bounds, snappingSteps: steps)) { newDefinition.bounds = bounds; } var min = new Vector3(Mathf.Min(bounds.min.x, bounds.max.x), Mathf.Min(bounds.min.y, bounds.max.y), Mathf.Min(bounds.min.z, bounds.max.z)); var max = new Vector3(Mathf.Max(bounds.min.x, bounds.max.x), Mathf.Max(bounds.min.y, bounds.max.y), Mathf.Max(bounds.min.z, bounds.max.z)); var size = (max - min); var heightStart = bounds.max.y + (bounds.size.y < 0 ? size.y : 0); var edgeHeight = heightStart - stepHeight * stepCount; var pHeight0 = new Vector3(min.x, edgeHeight, max.z); var pHeight1 = new Vector3(max.x, edgeHeight, max.z); var depthStart = bounds.min.z - (bounds.size.z < 0 ? size.z : 0); var pDepth0 = new Vector3(min.x, max.y, depthStart + stepDepthOffset); var pDepth1 = new Vector3(max.x, max.y, depthStart + stepDepthOffset); if (handles.DoTurnHandle(ref bounds)) { newDefinition.bounds = bounds; } if (handles.DoEdgeHandle1D(out edgeHeight, Axis.Y, pHeight0, pHeight1, snappingStep: stepHeight)) { var totalStepHeight = Mathf.Clamp((heightStart - edgeHeight), size.y % stepHeight, size.y); const float kSmudgeValue = 0.0001f; var oldStepCount = newDefinition.StepCount; var newStepCount = Mathf.Max(1, Mathf.FloorToInt((Mathf.Abs(totalStepHeight) + kSmudgeValue) / stepHeight)); newDefinition.stepDepth = (oldStepCount * newDefinition.stepDepth) / newStepCount; newDefinition.plateauHeight = size.y - (stepHeight * newStepCount); } if (handles.DoEdgeHandle1D(out stepDepthOffset, Axis.Z, pDepth0, pDepth1, snappingStep: ChiselLinearStairsDefinition.kMinStepDepth)) { stepDepthOffset -= depthStart; stepDepthOffset = Mathf.Clamp(stepDepthOffset, 0, this.absDepth - ChiselLinearStairsDefinition.kMinStepDepth); newDefinition.stepDepth = ((this.absDepth - stepDepthOffset) / this.StepCount); } float heightOffset; var prevModified = handles.modified; { var direction = Vector3.Cross(Vector3.forward, pHeight0 - pDepth0).normalized; handles.DoEdgeHandle1DOffset(out var height0vec, Axis.Y, pHeight0, pDepth0, direction, snappingStep: stepHeight); handles.DoEdgeHandle1DOffset(out var height1vec, Axis.Y, pHeight1, pDepth1, direction, snappingStep: stepHeight); var height0 = Vector3.Dot(direction, height0vec); var height1 = Vector3.Dot(direction, height1vec); if (Mathf.Abs(height0) > Mathf.Abs(height1)) { heightOffset = height0; } else { heightOffset = height1; } } if (prevModified != handles.modified) { newDefinition.plateauHeight += heightOffset; } } if (handles.modified) { this = newDefinition; } }
// // TODO: code below needs to be cleaned up & simplified // static void DraggableRadius(IChiselHandles handles, ref float diameterX, ref float diameterZ, Vector3 center, Vector3 up, Vector3 xVector, Vector3 zVector, IChiselHandle[] radiusHandles, bool isEllipsoid) { if (isEllipsoid) { Debug.Assert(radiusHandles.Length == 4); diameterX = -diameterX; handles.DoSlider1DHandle(ref diameterX, center, xVector, radiusHandles[1]); // right if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterX = -diameterX; handles.DoSlider1DHandle(ref diameterX, center, xVector, radiusHandles[0]); // left if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterZ = -diameterZ; handles.DoSlider1DHandle(ref diameterZ, center, zVector, radiusHandles[3]); // back if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterZ = -diameterZ; handles.DoSlider1DHandle(ref diameterZ, center, zVector, radiusHandles[2]); // forward if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterX = Mathf.Abs(diameterX); diameterZ = Mathf.Abs(diameterZ); } else { Debug.Assert(radiusHandles.Length == 1); handles.DoDistanceHandle(ref diameterX, center, up, radiusHandles[0]); // left diameterX = Mathf.Abs(diameterX); var radiusX = diameterX * 0.5f; if (handles.lastHandleHadFocus) { if (handles.TryGetClosestPoint(radiusHandles, out var closestPoint, interpolate: false)) { var vec = (closestPoint - center); handles.RenderDistanceMeasurement(center, center + vec, radiusX); } } } }