// for human agents bool ApplyDamage(AgentHuman inAgent, Vector3 inExplosionPos, float inDmgMultiplier) { Vector3 tmp = ClosestPoint.PointBounds(inExplosionPos, inAgent.CharacterController.bounds); float dist = (inExplosionPos - tmp).sqrMagnitude; if (dist > damageRadius * damageRadius) { return(false); } #if DEBUG DebugDraw.Diamond(Color.grey, 0.02f, tmp); DebugDraw.LineOriented(Color.grey, inExplosionPos, tmp, 0.04f); #endif int idx = inAgent.ExplosionHitTargets != null ? inAgent.ExplosionHitTargets.Length : 0; while (idx-- > 0) { if (CheckHit(inAgent.ExplosionHitTargets[idx], inExplosionPos, ref tmp)) { float coef = 1.0f - Mathf.Clamp01(Mathf.Sqrt(dist) / damageRadius); Damage = BaseDamage * coef * inDmgMultiplier; Impulse = tmp; inAgent.SendMessage("OnExplosionHit", this, SendMessageOptions.DontRequireReceiver); return(true); } } return(false); }
public LedgeAnchor GetAnchor(float3 position) { LedgeAnchor result = new LedgeAnchor(); float3 closestPoint = ClosestPoint.FromPosition(position, vertices[0], vertices[1]); float minimumDistance = math.length(closestPoint - position); result.distance = math.length(closestPoint - vertices[0]); int numEdges = vertices.Length; for (int i = 1; i < numEdges; ++i) { closestPoint = ClosestPoint.FromPosition(position, vertices[i], vertices[GetNextEdgeIndex(i)]); float distance = math.length(closestPoint - position); if (distance < minimumDistance) { minimumDistance = distance; result.index = i; result.distance = math.length(closestPoint - vertices[i]); } } result.distance = math.clamp( result.distance, 0.0f, GetLength(result.index)); return(result); }
public LedgeAnchor UpdateAnchor(LedgeAnchor anchor, float3 position) { int a = anchor.index; int b = GetNextEdgeIndex(anchor.index); float3 closestPoint = ClosestPoint.FromPosition(position, vertices[a], vertices[b]); LedgeAnchor result; float length = math.length(vertices[b] - vertices[a]); float distance = math.length(closestPoint - vertices[a]); if (distance > length) { result.distance = distance - length; result.index = GetNextEdgeIndex(anchor.index); return(result); } else if (distance < 0.0f) { result.index = GetPreviousEdgeIndex(anchor.index); result.distance = GetLength(result.index) + distance; return(result); } result.distance = distance; result.index = anchor.index; return(result); }
//----------------------------------------------------------------------------------------------------------------- public static float PointRay(Vector3 P, // point Vector3 RayO, Vector3 RayD) // ray origin & direction { return(Vector3.SqrMagnitude(P - ClosestPoint.PointRay(P, RayO, RayD))); }
//----------------------------------------------------------------------------------------------------------------- public static float PointSegment(Vector3 P, // point Vector3 S0, Vector3 S1) // end-points of line-segment { return(Vector3.SqrMagnitude(P - ClosestPoint.PointSegment(P, S0, S1))); }
public static AutomorpherRecipe Make(Geometry parentGeometry, Geometry childGeometry) { var parentLimit0Stencils = parentGeometry.MakeStencils(StencilKind.LimitStencils, 0); var subdivider = new Subdivider(parentLimit0Stencils); var parentLimit0VertexPositions = subdivider.Refine(parentGeometry.VertexPositions, new Vector3Operators()); List <(List <WeightedIndex>, Vector3)> resultPairs = Enumerable.Range(0, childGeometry.VertexCount) .AsParallel().AsOrdered() .Select(childVertexIdx => { Vector3 graftVertex = childGeometry.VertexPositions[childVertexIdx]; ClosestPoint.PointOnMesh closestPointOnBaseMesh = ClosestPoint.FindClosestPointOnMesh(parentGeometry.Faces, parentLimit0VertexPositions, graftVertex); var merger = new WeightedIndexMerger(); merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxA), closestPointOnBaseMesh.BarycentricWeights.X); merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxB), closestPointOnBaseMesh.BarycentricWeights.Y); merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxC), closestPointOnBaseMesh.BarycentricWeights.Z); var cloestPointAsVector = closestPointOnBaseMesh.AsPosition(parentLimit0VertexPositions); return(merger.GetResult(), cloestPointAsVector); }) .ToList(); List <List <WeightedIndex> > baseDeltaWeights = resultPairs.Select(t => t.Item1).ToList(); Vector3[] parentSurfacePositions = resultPairs.Select(t => t.Item2).ToArray(); var packedBaseDeltaWeights = PackedLists <WeightedIndex> .Pack(baseDeltaWeights); return(new AutomorpherRecipe(packedBaseDeltaWeights, parentSurfacePositions)); }
private RigidBone MapPositionToBone(Vector3 position, ControlVertexInfo[] previousFrameControlVertexInfos) { Vector3[] previousFrameControlVertexPositions = previousFrameControlVertexInfos.Select(vertexInfo => vertexInfo.position).ToArray(); int faceIdx = ClosestPoint.FindClosestFaceOnMesh(inverterParameters.ControlFaces, previousFrameControlVertexPositions, position); int boneIdx = inverterParameters.ControlFaceToBoneMap[faceIdx]; var bone = boneSystem.Bones[boneIdx]; return(bone); }
public static AffineTransform GetClosestTransform(float3 v0, float3 v1, float3 p) { float3 closestPoint = ClosestPoint.FromPosition(p, v0, v1); float3 up = Missing.up; float3 edge = math.normalize(v1 - v0); float3 n = math.cross(edge, up); quaternion q = math.quaternion(math.float3x3(-edge, up, -n)); return(new AffineTransform(closestPoint, q)); }
// for human agents bool CheckHit(Collider inCollider, Vector3 inExplosionPos, ref Vector3 outImpulse) { Vector3 closestPoint = ClosestPoint.PointBounds(inExplosionPos, inCollider.bounds); if (IsCollisionBetween(inExplosionPos, closestPoint, inCollider)) { return(false); } outImpulse = inCollider.bounds.center - inExplosionPos; outImpulse.y = closestPoint.y - inExplosionPos.y; outImpulse.Normalize(); outImpulse *= m_WeaponImpulse; return(true); }
// o //Test whether the line intersects (or lies inside) the frustum. +-----+ //NOTE: For performance reasons we're not doing a precise Intersect/Inside test. The function returns Inside in both cases. |/ | //FIXME: This function is not accurate, returns outside in case the line crosses corners near the frustum edge! Something like -> o+-----+ public static E_Location LineInFrustumFast(Vector3 lineStart, Vector3 lineEnd) { //check if any of the line point lies inside if (PointInFrustum(lineStart) != E_Location.Outside) { return(E_Location.Inside); } if (PointInFrustum(lineEnd) != E_Location.Outside) { //NOTE: if interested whether the whole line lies Inside, we'd need to check both lineStart and lineEnd before returning... return(E_Location.Inside); } //compute the nearest point between line and camera direction Vector3 p = ClosestPoint.PointOfTwoLines(lineStart, lineEnd, CameraPos, CameraPos + CameraDir * Far); return(PointInFrustum(p)); }
// for others float ComputeDamage(Collider inVictim, Vector3 inExplosionPos, ref Vector3 outImpulse) { Vector3 closestPoint = ClosestPoint.PointBounds(inExplosionPos, inVictim.bounds); float distance = Vector3.Distance(closestPoint, inExplosionPos); if ((distance >= damageRadius) || (IsCollisionBetween(inExplosionPos, closestPoint, inVictim) == true)) { return(-1.0f); } float coef = 1.0f - Mathf.Clamp01(distance / damageRadius); float dmg = BaseDamage * coef; outImpulse = inVictim.bounds.center - inExplosionPos; outImpulse.y = closestPoint.y - inExplosionPos.y; outImpulse.Normalize(); outImpulse *= m_WeaponImpulse; return(dmg); }
private static ClosestPoint CalculateClosestPoint(PathCreator pathCreator, EndOfPathInstruction endOfPath, Vector3 targetPosition) { var stepScale = pathCreator.path.length % 10; stepScale = Mathf.Clamp(stepScale, 1, 500f); var pathStep = pathCreator.path.length / stepScale; ClosestPoint closestPoint = new ClosestPoint(Vector3.zero, -1, 0); for (int i = 0; i < stepScale; i++) { var travelledDistance = pathStep * i; var pathPoint = pathCreator.path.GetPointAtDistance(travelledDistance, endOfPath); var vectorToTarget = targetPosition - pathPoint; vectorToTarget.y = 0; var distanceToTarget = vectorToTarget.magnitude; if (distanceToTarget < closestPoint.DistanceToTarget || closestPoint.DistanceToTarget == -1) { closestPoint = new ClosestPoint(vectorToTarget, distanceToTarget, travelledDistance); } } return(closestPoint); }
public override Contact this[int index] { get { var contact = Contact.Create( startPosition, endPosition); contact.shape = null; Transform currentTransform = raycastHits[index].collider.transform; while (currentTransform != null) { if (currentTransform == collider.transform) { return(contact); } currentTransform = currentTransform.parent; } contact.contact = raycastHits[index]; contact.contactCollider = raycastHits[index].collider; contact.contactPoint = raycastHits[index].point; contact.contactNormal = raycastHits[index].normal; contact.contactDistance = raycastHits[index].distance; if (raycastHits[index].distance == 0f) { var(linePoint, colliderPoint) = ClosestPoint.FromLineSegment( contact.startPosition, contact.endPosition, contact.contactCollider, layerMask); if (Missing.IsNaN(colliderPoint)) { return(contact); } var delta = colliderPoint - linePoint; contact.contactOrigin = linePoint; contact.contactPoint = colliderPoint; contact.contactDistance = math.length(delta) - Radius; contact.contactPenetration = (contact.contactDistance < 0f); RaycastHit raycastHit; if (Raycast.ClosestHit( linePoint, math.normalizesafe(delta), out raycastHit, math.max(contact.contactDistance + Radius, Radius + 0.01f))) { contact.contactNormal = raycastHit.normal; } else if (contact.contactDistance < epsilon) { contact.contactNormal = math.normalizesafe(linePoint - colliderPoint); } } else { contact.contactOrigin = ClosestPoint.FromPosition( contact.contactPoint, contact.startPosition, contact.endPosition); } contact.contactNormal = math.normalizesafe(contact.contactOrigin - contact.contactPoint); contact.shape = this; return(contact); } }
public override float3 FromPosition(float3 position, float3 origin) { return(ClosestPoint.FromPosition(origin, Bottom(position), Top(position), Radius)); }
void InitializeSupport(float3 position) { var rayStartPosition = position + (math.up() * groundProbeOffset); var rayDirection = -math.up(); var rayLength = groundProbeOffset + groundProbeLength; RaycastHit raycast; bool isGrounded = Raycast.ClosestHit( rayStartPosition, rayDirection, out raycast, rayLength, layerMask, transform); if (isGrounded) { isGrounded = (raycast.distance - groundProbeOffset < groundTolerance + epsilon); state.current.ground = raycast.collider.gameObject.transform; rayLength = raycast.distance + groundSupport; } if (!isGrounded) { float3 closestPoint = raycast.point; rayStartPosition = position + (math.up() * groundSupport); Collider[] colliders = null; var numContacts = Intersection.OverlapSphere( rayStartPosition, groundSupport * oneOverCos45, out colliders, layerMask, transform); bool ignore = false; if (colliders == null || numContacts == 0) { ignore = true; isGrounded = false; } else if (numContacts == 1) { var result = ClosestPoint.FromPosition( rayStartPosition, colliders[0]); if (!Missing.IsNaN(result)) { closestPoint = result; var closestPointLocal = state.current.InverseTransformPoint( closestPoint); closestPointLocal.y = 0f; if (closestPointLocal.magnitude > (groundSupport * 0.25f)) { ignore = true; isGrounded = false; } } } else { for (int i = 0; i < numContacts; i++) { if (colliders[i] == raycast.collider) { continue; } var candidatePoint = ClosestPoint.FromPosition( rayStartPosition, colliders[i]); if (Missing.IsNaN(candidatePoint)) { continue; } var candidatePointLocal = state.current.InverseTransformPoint(candidatePoint); if (candidatePointLocal.y >= groundSupport + epsilon) { continue; } if (-candidatePointLocal.y > groundTolerance + epsilon) { continue; } candidatePointLocal.y = 0f; if (math.length(candidatePointLocal) < (groundSupport * 0.25f)) { closestPoint = candidatePoint; isGrounded = true; break; } } } if (!ignore) { var closestPointToRayStart = closestPoint - rayStartPosition; rayDirection = math.normalizesafe(closestPointToRayStart); rayLength = math.length(closestPointToRayStart) + groundTolerance; var rayCastResult = Raycast.ClosestHit( rayStartPosition, rayDirection, out raycast, rayLength, layerMask, transform); if (rayCastResult) { float groundDistance = raycast.distance - groundSupport; isGrounded = groundDistance < (groundTolerance + epsilon) * oneOverCos45; state.current.ground = raycast.collider.gameObject.transform; } } } state.current.isGrounded = isGrounded; }
float GetGroundDistance(float3 position) { var rayStartPosition = position + (math.up() * groundProbeOffset); var rayDirection = -math.up(); var rayLength = groundProbeOffset + groundProbeLength; bool isGrounded = false; RaycastHit raycast; var rayCastResult = Raycast.ClosestHit( rayStartPosition, rayDirection, out raycast, rayLength, layerMask, transform); var distance = float.MaxValue; if (rayCastResult) { var tolerance = (groundSnap ? groundSnapDistance : groundTolerance); isGrounded = raycast.distance - groundProbeOffset < tolerance + epsilon; distance = raycast.distance - groundProbeOffset; state.current.ground = raycast.collider.transform; } if (!isGrounded) { float3 closestPoint = raycast.point; rayStartPosition = position + (math.up() * groundSupport); Collider[] colliders = null; int numContacts = Intersection.OverlapSphere( rayStartPosition, groundSupport * oneOverCos45, out colliders, layerMask, transform); bool ignore = false; if (colliders == null || numContacts == 0) { ignore = true; isGrounded = false; } else if (numContacts == 1) { var result = ClosestPoint.FromPosition( position + math.up() * 0.05f, colliders[0]); if (!Missing.IsNaN(result)) { closestPoint = result; var closestPointLocal = state.current.InverseTransformPoint(closestPoint); closestPointLocal.y = 0f; if (closestPointLocal.magnitude < groundSupport) { ignore = false; isGrounded = true; } else { ignore = true; isGrounded = false; } } } else { for (int i = 0; i < numContacts; i++) { if (colliders[i] == raycast.collider) { continue; } var candidatePoint = ClosestPoint.FromPosition( position + math.up() * 0.05f, colliders[i]); if (Missing.IsNaN(candidatePoint)) { continue; } var candidatePointLocal = state.current.InverseTransformPoint(candidatePoint); if (candidatePointLocal.y >= groundSupport + epsilon) { continue; } candidatePointLocal.y = 0f; if (math.length(candidatePointLocal) < groundSupport) { closestPoint = candidatePoint; isGrounded = true; break; } } } if (!ignore) { var closestPointLocal = state.current.InverseTransformPoint(closestPoint); rayStartPosition = closestPoint + (math.up() * groundSupport); rayDirection = -math.up(); rayLength = groundSupport + groundTolerance; rayCastResult = Raycast.ClosestHit( rayStartPosition, rayDirection, out raycast, rayLength, layerMask, transform); if (rayCastResult) { distance = raycast.distance - groundSupport - closestPointLocal.y; isGrounded = distance < (groundTolerance + epsilon) * oneOverCos45; state.current.ground = raycast.collider.gameObject.transform; } } } return(distance); }
private static void Knn_OnClassify(Point2D NewNode, IEnumerable <Point2D> ClosestKPoints, string MostTag, IEnumerable <Point2D> ClassifiedNodes) { Console.WriteLine("NewPoint,x:{0},y:{1}\t,closet points in {2}", NewNode.x, NewNode.y, k); foreach (var ClosestPoint in ClosestKPoints) { Console.WriteLine("Point,x:{0},y:{1}\t,tag:{2},distance{3}", ClosestPoint.x, ClosestPoint.y, ClosestPoint.Tag, ClosestPoint.GetEuclideanDistance(NewNode)); } Console.WriteLine("MostTag:{0}", MostTag); Console.WriteLine("----------------------------------"); List <Point2D> point2Ds = new List <Point2D>(); point2Ds.AddRange(ClassifiedNodes); StringBuilder sb = new StringBuilder(); sb.Append("Round:"); sb.Append(Round++); sb.Append(" ,AddPoint At:"); sb.Append(NewNode.x); sb.Append(","); sb.Append(NewNode.y); sb.Append(",Tag:"); sb.Append(NewNode.Tag); Points2DCollectionsViewer View = Points2DCollectionsViewer.BuildViewer(point2Ds, sb.ToString(), 0, NodesMaxValueSet); View.AddMarkAt(NewNode, 20, 7); foreach (var ClosestPoint in ClosestKPoints) { View.AddMarkAt(ClosestPoint, 6, 7); } Points2DCollectionsViewer.ShowViewer(View); }
public override Contact this[int index] { get { var contact = Contact.Create( startPosition, float3.zero); contact.shape = null; Transform currentTransform = raycastHits[index].collider.transform; if (currentTransform == collider.transform) { return(contact); } while (currentTransform != null) { if (currentTransform == collider.transform) { return(contact); } currentTransform = currentTransform.parent; } contact.contact = raycastHits[index]; contact.contactOrigin = contact.startPosition; contact.contactCollider = raycastHits[index].collider; contact.contactPoint = raycastHits[index].point; contact.contactNormal = raycastHits[index].normal; contact.contactDistance = raycastHits[index].distance; if (raycastHits[index].distance == 0f) { var colliderPoint = ClosestPoint.FromPosition(contact.startPosition, contact.contactCollider, layerMask); if (Missing.IsNaN(colliderPoint)) { return(contact); } float3 delta = colliderPoint - contact.startPosition; if (math.abs(math.length(delta) - Radius) < epsilon) { float dot = math.dot(math.normalizesafe(delta), direction); if (dot <= -0.8f) { return(contact); } } contact.contactOrigin = contact.startPosition; contact.contactPoint = colliderPoint; contact.contactDistance = math.length(delta) - Radius; contact.contactPenetration = (contact.contactDistance < 0f); RaycastHit raycastHit; if (Raycast.ClosestHit(contact.startPosition, math.normalizesafe(delta), out raycastHit, Mathf.Max(contact.contactDistance + Radius, Radius + 0.01f))) { contact.contactNormal = raycastHit.normal; } else if (contact.contactDistance < epsilon) { contact.contactNormal = math.normalizesafe(contact.startPosition - colliderPoint); } } if (!Missing.equalEps(direction, -Missing.up, epsilon)) { RaycastHit raycastHit; if (Raycast.ClosestHit(contact.contactPoint - (direction * distance), direction, out raycastHit, distance + Radius, -1, collider.transform)) { contact.contactNormal = raycastHit.normal; } } contact.shape = this; return(contact); } }