/// <summary> /// Get the intersection between a line and a plane. // If the line and plane are not parallel, the function outputs true, otherwise false. /// </summary> /// <param name="intersection"></param> /// <param name="ray"></param> /// <param name="plane"></param> /// <returns></returns> public static bool LinePlaneIntersection(out Vector3 intersection, Ray ray, ExtPlane plane) { float length; float dotNumerator; float dotDenominator; Vector3 vector; intersection = Vector3.zero; //calculate the distance between the linePoint and the line-plane intersection point dotNumerator = Vector3.Dot((plane.Point - ray.origin), plane.Normal); dotDenominator = Vector3.Dot(ray.direction, plane.Normal); //line and plane are not parallel if (dotDenominator != 0.0f) { length = dotNumerator / dotDenominator; //create a vector from the linePoint to the intersection point vector = ExtVector3.SetVectorLength(ray.direction, length); //get the coordinates of the line-plane intersection point intersection = ray.origin + vector; return(true); } //output not valid else { return(false); } }
/// <summary> /// draw a line /// </summary> public static bool DrawLineTrunk(bool trunk, Vector3 p1, Vector3 p2, Color color, float size, out bool hasChanged) { hasChanged = false; Vector3 direction = (p1 - p2); Vector3 middle = ExtVector3.GetMeanOfXPoints(p1, p2); Quaternion rotation = ExtQuaternion.QuaternionFromLine(p1, p2, Vector3.up); Handles.color = color; float scaleCylinder = direction.magnitude; if (!trunk) { Matrix4x4 scaleMatrix = Matrix4x4.TRS(middle, rotation, new Vector3(size, size, scaleCylinder)); using (new Handles.DrawingScope(scaleMatrix)) { Handles.CylinderHandleCap(0, Vector3.zero, Quaternion.identity, 1, EventType.Repaint); } } if (!Event.current.alt && Event.current.button != 2 && Handles.Button( middle, rotation, scaleCylinder, scaleCylinder, ExtGravityOverrideEditor.LineHandleCap)) { trunk = !trunk; hasChanged = true; Use(); } return(trunk); }
//Returns true if "point" is in a rectangle mad up of RectA to RectD. The line point is assumed to be on the same //plane as the rectangle. If the point is not on the plane, use ProjectPointOnPlane() first. public static bool IsPointIn2DRectangle(Vector3 point, Vector3 rectA, Vector3 rectC, Vector3 rectB, Vector3 rectD) { Vector3 vector; Vector3 linePoint; //get the center of the rectangle vector = rectC - rectA; float size = -(vector.magnitude / 2f); vector = ExtVector3.AddVectorLength(vector, size); Vector3 middle = rectA + vector; Vector3 xVector = rectB - rectA; float width = xVector.magnitude / 2f; Vector3 yVector = rectD - rectA; float height = yVector.magnitude / 2f; linePoint = ExtLine.ProjectPointOnLine(middle, xVector.normalized, point); vector = linePoint - point; float yDistance = vector.magnitude; linePoint = ExtLine.ProjectPointOnLine(middle, yVector.normalized, point); vector = linePoint - point; float xDistance = vector.magnitude; if ((xDistance <= width) && (yDistance <= height)) { return(true); } else { return(false); } }
/// <summary> /// Raycast from mouse Position in scene view for future mouseClick object /// </summary> public static HitSceneView SetCurrentOverObject(HitSceneView newHit, bool setNullIfNot = true) { RaycastHit _saveRaycastHit; Ray worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); //first a test only for point //if (Physics.Raycast(worldRay, out saveRaycastHit, Mathf.Infinity, 1 << LayerMask.NameToLayer(gravityAttractorEditor.layerPoint), QueryTriggerInteraction.Ignore)) if (Physics.Raycast(worldRay, out _saveRaycastHit, Mathf.Infinity)) { if (_saveRaycastHit.collider.gameObject != null) { newHit.objHit = _saveRaycastHit.collider.gameObject; newHit.pointHit = _saveRaycastHit.point; newHit.normal = _saveRaycastHit.normal; } } else { if (setNullIfNot) { newHit.objHit = null; newHit.pointHit = ExtVector3.GetNullVector(); } } return(newHit); }
public virtual void UpdatePosition() { Vector3 target = _spline.EvaluatePositionAtUnit(_pathPosition, _positionUnits) + _toMove.right * _offsetFromSpline.x + _toMove.up * _offsetFromSpline.y; _toMove.position = ExtVector3.OwnSmoothDamp(_toMove.position, target, ref _refPositionVelocity, _dampingTimePosition, Mathf.Infinity, Time.fixedDeltaTime); }
//public static void GenerateAndSwitchBranch(ControllerStick stick, SplineBase splineA, SplineBase splineB, float from, float to, SplineBase.PositionUnits positionUnits) //{ // SplineBase generatedSpline = BranchBetweenSplines.GenerateBranch(splineA, splineB, from, to, positionUnits); // stick.ChangeSpline(generatedSpline, 0); //} public void BasicPositionAndOffset(float offset) { Vector3 target = PositionWithoutOffsetFromSpline(offset) + _toMove.right * _offsetFromSpline.x + _toMove.up * _offsetFromSpline.y; _toMove.position = ExtVector3.OwnSmoothDamp(_toMove.position, target, ref _refPositionVelocity, _dampingTimePosition, Mathf.Infinity, Time.fixedDeltaTime); }
//This helps keep the size consistent no matter how far we are from it. float GetDistanceMultiplier() { if (_target == null) { return(0f); } return(Mathf.Max(.01f, Mathf.Abs(ExtVector3.MagnitudeInDirection(_target.position - transform.position, MyCamera.transform.forward)))); }
/// <summary> /// return true if the position is inside the sphape /// </summary> /// <param name="otherPosition">position to test</param> /// <returns>true if inside the shape</returns> public bool IsInsideShape(Vector3 otherPosition) { if (_circle.IsAbove(otherPosition)) { return(ExtVector3.Distance(otherPosition, Position) <= _realRadius); } return(false); }
public Vector3 GetActualAccelerationForward() { Vector3 dirForward = GetActualDirForward(); Vector3 dirVelocity = rb.velocity; Vector3 projected = ExtVector3.GetProjectionOfAOnB(dirVelocity, dirForward, baseGravity.GetMainAndOnlyGravity()); //Debug.DrawRay(rb.transform.position, dirForward, Color.blue); //Debug.DrawRay(rb.transform.position, dirVelocity, Color.red); //Debug.DrawRay(rb.transform.position, projected, Color.green); return(projected); }
/// 2 ------2------ 3 /// 1 | 3 | /// 1 ------4----- 4 | /// | | 3 | | /// | 4| | 2 | /// | 1 | /// | | /// public ExtQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4) : this() { _position = ExtVector3.GetMeanOfXPoints(p1, p2, p3, p4); Vector3 x = p1 - p2; Vector3 y = p1 - p4; Vector3 up = Vector3.Cross(x, y); _rotation = ExtRotation.QuaternionFromVectorDirector(up, x.FastNormalized()); _rotation = ExtRotation.RotateQuaternion(_rotation, new Vector3(-90, 0, 0)); _localScale = new Vector3(y.magnitude, 1, x.magnitude); UpdateMatrix(); }
private void ApplyChange() { //_camera.transform.position = _follow.position; //_camera.transform.LookAt(_lookAt, _upReference.up); _camera.transform.position = ExtVector3.OwnSmoothDamp(_camera.transform.position, _follow.position, ref _refPositionVelocity, _dampingPosition, Mathf.Infinity, Time.deltaTime); Quaternion targetRotation = Quaternion.LookRotation(_lookAt.position - _camera.transform.position, _upReference.up); //target = target * Quaternion.Euler(_offsetRotation); _camera.transform.rotation = ExtRotation.OwnSmoothDamp(_camera.transform.rotation, targetRotation, ref _refRotationVelocity, _dampingLookAt, Time.deltaTime); }
private static void GroupGravityFields() { GameObject[] selected = Selection.gameObjects; if (selected.Length == 0) { return; } List <GameObject> selectedWithAttractor = new List <GameObject>(selected.Length); for (int i = 0; i < selected.Length; i++) { Attractor action = selected[i].GetComponentInChildren <Attractor>(); if (action != null) { selectedWithAttractor.Add(selected[i]); } } //first, do not group anything if one of them is already grouped for (int i = 0; i < selectedWithAttractor.Count; i++) { AttractorGroup parent = selectedWithAttractor[i].GetComponentInParent <AttractorGroup>(); if (parent != null) { return; } } Selection.activeGameObject = null; Transform commonParent = ExtObjectEditor.FindCommonParent(selectedWithAttractor, selectedWithAttractor[0].transform.parent); EditorGUIUtility.PingObject(commonParent); GameObject newParent = new GameObject("AttractorGroup"); newParent.transform.position = ExtVector3.GetMeanOfXPoints(selectedWithAttractor.ToArray(), out Vector3 sizeBoundingBox, true); AttractorGroup newGroup = newParent.AddComponent <AttractorGroup>(); //UnityEditor.Editor splineEditorGeneric = UnityEditor.Editor.CreateEditor(newGroup, typeof(GravityFieldsGroupEditor)); //GravityFieldsGroupEditor groupEditor = (GravityFieldsGroupEditor)splineEditorGeneric; //groupEditor.FillGroupList(selectedWithGravityFieldsAction); SetupSiblingOfNewGroup(selectedWithAttractor, commonParent, newParent); ExtReflection.SetExpanded(newParent, true); ExtReflection.Rename(newParent); }
/// <summary> /// from a given point in space, order the face, from the closest to the farrest from the point /// /// cube /// 6 ------------ 7 /// / | 3 / | /// 5 ------------ 8 | /// | | | | /// | 5 | 6 | 2-|------------ face /// | | 1 | | /// | 2 ----------|-- 3 /// |/ 4 | / /// 1 ------------ 4 /// </summary> /// <returns></returns> public static FloatRange[] GetOrdersOfFaceFromPoint(ExtCube cube, Vector3 point) { FloatRange[] faceDistance = new FloatRange[6]; faceDistance[0] = new FloatRange(1, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P1, cube.P5, cube.P8, cube.P4), point)); faceDistance[1] = new FloatRange(2, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P4, cube.P8, cube.P7, cube.P3), point)); faceDistance[2] = new FloatRange(3, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P5, cube.P6, cube.P7, cube.P8), point)); faceDistance[3] = new FloatRange(4, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P1, cube.P2, cube.P3, cube.P4), point)); faceDistance[4] = new FloatRange(5, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P2, cube.P6, cube.P5, cube.P1), point)); faceDistance[5] = new FloatRange(6, ExtVector3.DistanceSquared(ExtVector3.GetMeanOfXPoints(cube.P3, cube.P7, cube.P6, cube.P2), point)); faceDistance = FloatRange.Sort(faceDistance); return(faceDistance); }
public static Vector3 GetMiddleOfXVector(Vector3[] arrayVect) { Vector3 sum = Vector3.zero; for (int i = 0; i < arrayVect.Length; i++) { if (ExtVector3.IsNullVector(arrayVect[i])) { continue; } sum += arrayVect[i]; } return((sum).normalized); }
//This function returns a point which is a projection from a point to a plane. public static Vector3 ProjectPointInPlaneMethod2(Vector3 planeNormal, Vector3 planePoint, Vector3 point) { float distance; Vector3 translationVector; //First calculate the distance from the point to the plane: distance = SignedDistancePlanePoint(planeNormal, planePoint, point); //Reverse the sign of the distance distance *= -1; //Get a translation vector translationVector = ExtVector3.SetVectorLength(planeNormal, distance); //Translate the point to form a projection return(point + translationVector); }
/// <summary> /// take into acount unidirectinnal option, return null if not found /// </summary> /// <returns></returns> private Vector3 GetGoodPointUnidirectionnal(Vector3 p, Vector3 foundPosition) { //Vector3 projectedOnPlane = TriPlane.Project(EdgeAb.A, TriNorm.normalized, p); Vector3 dirPlayer = p - foundPosition; float dotPlanePlayer = ExtVector3.DotProduct(dirPlayer.normalized, TriNorm.normalized); if ((dotPlanePlayer < 0 && !inverseDirection) || dotPlanePlayer > 0 && inverseDirection) { return(foundPosition); } else { Debug.DrawRay(p, dirPlayer, Color.yellow, 5f); Debug.DrawRay(p, TriNorm.normalized, Color.black, 5f); return(ExtVector3.GetNullVector()); } }
/// <summary> /// save the last position on ground /// </summary> public void SaveLastPositionOnground() { if (entityController.GetMoveState() == EntityController.MoveState.InAir) { return; } worldLastNormal = playerGravity.GetMainAndOnlyGravity(); //avoir toujours une normal à jour float distForSave = (WorldLastPositionGetIndex(0) - entityController.rb.transform.position).sqrMagnitude; //Debug.Log("dist save: " + distForSave); //si la distance entre les 2 point est trop grande, dans tout les cas, save la nouvelle position ! if (distForSave > sizeDistanceForSavePlayerPos) { WorldLastPositionSet(entityController.rb.transform.position); //save la position onGround //ExtDrawGuizmos.DebugWireSphere(WorldLastPositionGetIndex(0), Color.red, 0.5f, 1f); } //si la normal à changé, update la position + normal ! else if (worldPreviousNormal != worldLastNormal) { //ici changement de position SEULEMENT si l'angle de la normal diffère de X float anglePreviousNormal = Vector3.Angle(worldPreviousNormal, entityController.rbRotateObject.up); float angleNormalPlayer = Vector3.Angle(worldLastNormal, entityController.rbRotateObject.up); //ici gérer les normal à zero ?? float diff; if (ExtVector3.IsAngleCloseToOtherByAmount(anglePreviousNormal, angleNormalPlayer, differenceAngleNormalForUpdatePosition, out diff)) { //Debug.Log("ici l'angle est trop proche, ducoup ne pas changer de position"); //ni de normal ?? } else { //ici change la normal, ET la position WorldLastPositionSet(entityController.rb.transform.position); //save la position onGround worldPreviousNormal = worldLastNormal; //ExtDrawGuizmos.DebugWireSphere(WorldLastPositionGetIndex(0), Color.yellow, 0.5f, 1f); //Debug.DrawRay(entityController.rb.transform.position, worldPreviousNormal, Color.yellow, 1f); } } }
public ExtCylinder(Vector3 p1, Vector3 p2, float radius = 0.25f) : this() { _position = ExtVector3.GetMeanOfXPoints(p1, p2); _rotation = ExtQuaternion.QuaternionFromLine(p1, p2, Vector3.up); _rotation = ExtRotation.RotateQuaternion(_rotation, new Vector3(90, 0, 0)); _localScale = new Vector3(1, 1, 1); _cylinderMatrix = Matrix4x4.TRS(_position, _rotation, _localScale * 1); //why radius a 0.25, and lenght * 0.8 ?? I don't know, //it's there to match the first constructor(position, rotation, scale) _radius = radius; _lenght = ExtVector3.Distance(p2, p1) * 0.8f; _lenghtSquared = _lenght * _lenght; _radiusSquared = _radius * _radius; _realRadius = _radius * MaxXY(_localScale); _realSquaredRadius = _realRadius * _realRadius; UpdateMatrix(); }
/// <summary> /// get closest point from an array of points /// </summary> public static Vector3 GetClosestPoint(Vector3 posEntity, Vector3[] arrayPos, ref int indexFound) { float sqrDist = 0; indexFound = -1; int firstIndex = 0; for (int i = 0; i < arrayPos.Length; i++) { if (ExtVector3.IsNullVector(arrayPos[i])) { continue; } float dist = (posEntity - arrayPos[i]).sqrMagnitude; if (firstIndex == 0) { indexFound = i; sqrDist = dist; } else if (dist < sqrDist) { sqrDist = dist; indexFound = i; } firstIndex++; } if (indexFound == -1) { //Debug.LogWarning("nothing found"); return(ExtVector3.GetNullVector()); } return(arrayPos[indexFound]); }
/// <summary> /// calculate the normal direction, based on the hit forward /// </summary> public void CalculateStraffDirection(Vector3 normalHit) { Vector3 playerDir = entityController.GetFocusedForwardDirPlayer(); //Debug.Log("ici calcul straff, normal hit: " + normalHit); //Debug.DrawRay(rb.transform.position, playerDir, Color.red, 5f); Vector3 upPlayer = playerGravity.GetMainAndOnlyGravity(); float dotWrongSide = Vector3.Dot(upPlayer, normalHit); //here the slope is nice for normal forward ? if (1 - dotWrongSide < dotMarginNiceSlope) { //Debug.Log("nice slope, do nothing: dot: " + dotWrongSide + "(max: " + dotMarginNiceSlope + ")"); playerStraff = entityController.GetFocusedForwardDirPlayer(); } else { //Debug.Log("can straff !"); Vector3 relativeDirPlayer = entityAction.GetRelativeDirection(); float dotRight = 0f; float dotLeft = 0f; int rightOrLeft = ExtVector3.IsRightOrLeft(normalHit, upPlayer, relativeDirPlayer, ref dotRight, ref dotLeft); Vector3 right = Vector3.Cross(normalHit, upPlayer); if (rightOrLeft == 1) { playerStraff = ExtVector3.GetProjectionOfAOnB(relativeDirPlayer, right, upPlayer, minMaxMagnitude.x, minMaxMagnitude.y);// right * (dotRight); if (groundForwardCheck.IsAdvancedForwardCastRightOrLeft()) { //Debug.LogWarning("zero ! warning, slide if not both " + playerStraff); if (playerStraff.magnitude < minMagnitudeSlideWhenCastRightOrLeft) { playerStraff = playerStraff.normalized * minMagnitudeSlideWhenCastRightOrLeft; } //playerStraff = right; } //Debug.DrawRay(rb.position, playerStraff, Color.magenta, 0.1f); //Debug.Log("ok right"); } else if (rightOrLeft == -1) { playerStraff = ExtVector3.GetProjectionOfAOnB(relativeDirPlayer, -right, upPlayer, minMaxMagnitude.x, minMaxMagnitude.y);//-right * dotLeft; if (groundForwardCheck.IsAdvancedForwardCastRightOrLeft()) { //Debug.LogWarning("zero ! warning, slide if not both" + playerStraff); if (playerStraff.magnitude < minMagnitudeSlideWhenCastRightOrLeft) { playerStraff = playerStraff.normalized * minMagnitudeSlideWhenCastRightOrLeft; } //playerStraff = -right; } //Debug.DrawRay(rb.position, playerStraff, Color.magenta, 0.1f); //Debug.Log("ok left"); } else { if (entityAction.GetDirInput().x < 0 && (entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.FORWARD_AND_LEFT || entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.FORWARD_AND_RIGHT)) { //Debug.Log("left ?"); playerStraff = -right; return; } else if (entityAction.GetDirInput().x < 0 && (entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.BEHIND_AND_LEFT || entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.BEHIND_AND_RIGHT)) { //Debug.Log("right ?"); playerStraff = right; return; } else if (entityAction.GetDirInput().x > 0 && (entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.FORWARD_AND_LEFT || entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.FORWARD_AND_RIGHT)) { //Debug.Log("right ?"); playerStraff = right; return; } else if (entityAction.GetDirInput().x > 0 && (entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.BEHIND_AND_LEFT || entityRotate.InputFromCameraOrientation == ExtRotation.OrientationRotation.BEHIND_AND_RIGHT)) { //Debug.Log("left ?"); playerStraff = -right; return; } //Debug.LogError("forward ???"); playerStraff = Vector3.zero; } } }
private void ForwardWallCheck() { RaycastHit hitInfo; ResetContact(); isAdvancedForward = isForwardAdvanceNormalOk = false; //do nothing if not moving if (!entityAction.IsMoving()) { return; } //do nothing if input and forward player are not equal if (!entityController.IsLookingTowardTheInput(dotMarginImpact)) { return; } AdvanceForwardCheck(); if (Physics.SphereCast(rb.transform.position, sizeRadiusForward, entityController.GetFocusedForwardDirPlayer(), out hitInfo, distForward, entityController.layerMask, QueryTriggerInteraction.Ignore)) { //if (!IsSphereGravityAndNormalNotOk(hitInfo)) // return; //ExtDrawGuizmos.DebugWireSphere(rb.transform.position + (entityController.GetFocusedForwardDirPlayer()) * (distForward), Color.yellow, sizeRadiusForward, 0.1f); //Debug.DrawRay(rb.transform.position, (entityController.GetFocusedForwardDirPlayer()) * (distForward), Color.yellow, 5f); //ExtDrawGuizmos.DebugWireSphere(hitInfo.point, Color.red, 0.1f, 0.1f); isForwardWall = true; Vector3 normalHit = hitInfo.normal; Vector3 upPlayer = entityGravity.GetMainAndOnlyGravity(); Vector3 tmpDirSurfaceNormal = ExtVector3.GetSurfaceNormal(rb.transform.position, entityController.GetFocusedForwardDirPlayer(), distForward, sizeRadiusForward, hitInfo.point, collRayCastMargin, entityController.layerMask); if (tmpDirSurfaceNormal != Vector3.zero) { dirSurfaceNormal = tmpDirSurfaceNormal; } entitySlide.CalculateStraffDirection(dirSurfaceNormal); //calculate SLIDE float dotWrongSide = Vector3.Dot(upPlayer, normalHit); if (dotWrongSide < -dotMarginImpact) { //Debug.Log("forward too inclined, dotImpact: " + dotWrongSide + "( max: " + dotMarginImpact + ")"); isForbiddenForward = true; return; } //int isForbidden = ExtList.ContainSubStringInArray(walkForbiddenForwardUp, LayerMask.LayerToName(hitInfo.transform.gameObject.layer)); if (!IsNormalOk(hitInfo)) { //here we are in front of a forbidden wall !! isForbiddenForward = true; entityBumpUp.HereBumpUp(hitInfo, dirSurfaceNormal); } else { if (groundCheck.IsFlying() && !inAirForwardWall) { isForbiddenForward = true; } else { //HERE FORWARD, DO SWITCH !! coolDownForward.StartCoolDown(timeBetween2TestForward); //Debug.Log("forward"); groundCheck.SetForwardWall(hitInfo); isForbiddenForward = false; } } } else { ResetContact(); } }
/// <summary> /// return true if the position is inside the sphape /// </summary> /// <param name="otherPosition">position to test</param> /// <returns>true if inside the shape</returns> public bool IsInsideShape(Vector3 otherPosition) { return(ExtVector3.Distance(otherPosition, Position) <= _realRadius); }
private static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime) { target = current + DeltaAngle(current, target); return(ExtVector3.OwnSmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime)); }
public Vector3 ClosestPointTo(Vector3 p) { // Find the projection of the point onto the edge var uab = EdgeAb.Project(p); var uca = EdgeCa.Project(p); bool isInPlane = false; Vector3 rightPositionIfOutsidePlane = CalculateCornerAndLine(p, uab, uca, ref isInPlane); if (!infinitePlane) { //ici on est dans un plan fini, si on dis de ne pas prendre //en compte les borders, juste tomber ! if (noGravityBorders && !isInPlane) { //Debug.Log("ici on est PAS dans le plane, juste tomber !"); return(ExtVector3.GetNullVector()); } else if (noGravityBorders && isInPlane) { //Debug.Log("ici on est DANS le plane, ET en noGravityBorder: tester la normal ensuite !"); if (unidirectionnal) { return(GetGoodPointUnidirectionnal(p, TriPlane.Project(EdgeAb.A, TriNorm.normalized, p))); //get the good point (or null) in a plane unidirectionnal } else { //ici en gravityBorder, et on est dans le plan, et c'esst multi directionnel, alors OK dac ! return(TriPlane.Project(EdgeAb.A, TriNorm.normalized, p)); } } else if (!noGravityBorders && unidirectionnal) { //here not infinite, and WITH borders AND unidirectionnal if (isInPlane) { return(GetGoodPointUnidirectionnal(p, TriPlane.Project(EdgeAb.A, TriNorm.normalized, p))); //get the good point (or null) in a plane unidirectionnal } else { return(GetGoodPointUnidirectionnal(p, rightPositionIfOutsidePlane)); } } else { //here Not infinite, WITH borders, NO unidirectionnal if (isInPlane) { return(TriPlane.Project(EdgeAb.A, TriNorm.normalized, p)); } else { return(rightPositionIfOutsidePlane); } } } else { if (unidirectionnal) { return(GetGoodPointUnidirectionnal(p, TriPlane.Project(EdgeAb.A, TriNorm.normalized, p))); //get the good point (or null) in a plane unidirectionnal } } //ici le plan est infini, OU fini mais on est dedant // The closest point is in the triangle so // project to the plane to find it //Vector3 projectedPoint = TriPlane.Project(EdgeAb.A, TriNorm.normalized, p); return(TriPlane.Project(EdgeAb.A, TriNorm.normalized, p)); }
IEnumerator TransformSelected(TransformType type) { isTransforming = true; totalScaleAmount = 0; totalRotationAmount = Quaternion.identity; Vector3 originalTargetPosition = _target.position; Vector3 planeNormal = (transform.position - _target.position).normalized; Vector3 axis = GetSelectedAxisDirection(); Vector3 projectedAxis = Vector3.ProjectOnPlane(axis, planeNormal).normalized; Vector3 previousMousePosition = Vector3.zero; while (!Input.GetMouseButtonUp(0)) { Ray mouseRay = MyCamera.ScreenPointToRay(Input.mousePosition); Vector3 mousePosition = Geometry.LinePlaneIntersect(mouseRay.origin, mouseRay.direction, originalTargetPosition, planeNormal); if (previousMousePosition != Vector3.zero && mousePosition != Vector3.zero) { if (type == TransformType.Move) { float moveAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projectedAxis) * moveSpeedMultiplier; _target.Translate(axis * moveAmount, Space.World); } if (type == TransformType.Scale) { Vector3 projected = (selectedAxis == Axis.Any) ? transform.right : projectedAxis; float scaleAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * scaleSpeedMultiplier; //WARNING - There is a bug in unity 5.4 and 5.5 that causes InverseTransformDirection to be affected by scale which will break negative scaling. Not tested, but updating to 5.4.2 should fix it - https://issuetracker.unity3d.com/issues/transformdirection-and-inversetransformdirection-operations-are-affected-by-scale Vector3 localAxis = (space == TransformSpace.Local && selectedAxis != Axis.Any) ? _target.InverseTransformDirection(axis) : axis; if (selectedAxis == Axis.Any) { _target.localScale += (ExtVector3.Abs(_target.localScale.normalized) * scaleAmount); } else { _target.localScale += (localAxis * scaleAmount); } totalScaleAmount += scaleAmount; } if (type == TransformType.Rotate) { if (selectedAxis == Axis.Any) { Vector3 rotation = transform.TransformDirection(new Vector3(Input.GetAxis("Mouse Y"), -Input.GetAxis("Mouse X"), 0)); _target.Rotate(rotation * allRotateSpeedMultiplier, Space.World); totalRotationAmount *= Quaternion.Euler(rotation * allRotateSpeedMultiplier); } else { Vector3 projected = (selectedAxis == Axis.Any || ExtVector3.IsParallel(axis, planeNormal)) ? planeNormal : Vector3.Cross(axis, planeNormal); float rotateAmount = (ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * rotateSpeedMultiplier) / GetDistanceMultiplier(); _target.Rotate(axis, rotateAmount, Space.World); totalRotationAmount *= Quaternion.Euler(axis * rotateAmount); } } NotifyTransformChanged(); } previousMousePosition = mousePosition; yield return(null); } totalRotationAmount = Quaternion.identity; totalScaleAmount = 0; isTransforming = false; }
/// <summary> /// Returns a rotation of up attempting to face in the general direction of forward. /// </summary> /// <param name="up"></param> /// <param name="targForward"></param> /// <returns></returns> public static Quaternion FaceRotation(Vector3 forward, Vector3 up) { forward = ExtVector3.GetForwardTangent(forward, up); return(Quaternion.LookRotation(forward, up)); }
/// <summary> /// Set isGrounded /// sphere cast down just beyond the bottom of the capsule to see/ /// if the capsule is colliding round the bottom /// </summary> private void GroundChecking(float magnitudeToCheck, ref bool groundValue, Vector3 dirRay) { if (entityJump && entityJump.IsJumpedAndNotReady()) { return; } //isGrounded = false; //return; RaycastHit hitInfo; //Vector3 dirRaycast = playerGravity.GetMainAndOnlyGravity() * (radius + magnitudeToCheck); //Debug.DrawRay(rb.transform.position, dirRaycast * -1, Color.blue, 0.1f); if (Physics.SphereCast(rb.transform.position, sizeRadiusRayCast, dirRay, out hitInfo, magnitudeToCheck, entityController.layerMask, QueryTriggerInteraction.Ignore)) { //si on est sur un mur Galaxy... if (entityController.IsMarioGalaxyPlatform(LayerMask.LayerToName(hitInfo.collider.gameObject.layer))) //&& !entityGravityAttractorSwitch.IsNormalIsOkWithCurrentGravity(hitInfo.normal, entityGravityAttractorSwitch.GetDirGAGravity())) { //si on était en l'air, test la gravité par rapport à la vrai gravité ! if (isFlying && !baseGravityAttractorSwitch.IsNormalIsOkWithCurrentGravity(hitInfo.normal, -baseGravityAttractorSwitch.GravityDirection)) { Debug.Log("here sphereAirMove tell us we are in a bad normal, (we were inAir before) continiue to fall"); groundValue = false; return; } else if (!isFlying && !baseGravityAttractorSwitch.IsNormalIsOkWithCurrentGravity(hitInfo.normal, baseGravityAttractorSwitch.GetWantedGravityOnGround())) { Debug.Log("here sphereAirMove tell us we are in a bad normal, (we were onGround Before, first time fly ?) continiue to fall"); groundValue = false; return; } } if (SetCurrentPlatform(hitInfo.collider.transform)) { //Debug.Log("test de fastForward ?"); } groundValue = true; if (calculateSurfaceNormal) { dirSurfaceNormal = ExtVector3.GetSurfaceNormal(rb.transform.position, baseGravity.GetMainAndOnlyGravity() * -0.01f, groundCheckDistance, sizeRadiusRayCast, hitInfo.point, collRayCastMargin, entityController.layerMask); } else { dirSurfaceNormal = hitInfo.normal; } bool previous = fastForward && fastForward.IsInFastForward() && !fastForward.SwithcingIsRunning(); if (CanChangeNormal(hitInfo)) { dirNormal = hitInfo.normal; pointHit = hitInfo.point; if (fastForward && previous && fastForward.IsInFastForward()) { //Debug.LogWarning("mmm ici ???"); dirNormal = dirSurfaceNormal; } /* * Vector3 tmpOrientedGravity = dirNormal; * if (fastForward && fastForward.DoChangeOrientationManually(hitInfo, ref tmpOrientedGravity)) * { * Debug.LogWarning("ici fast forwaard"); * dirNormal = tmpOrientedGravity.normalized; * } */ } } else { groundValue = false; //dirNormal = baseGravity.GetMainAndOnlyGravity() * 1; } }
public double Project(Vector3 p) => ExtVector3.DotProduct(Delta, p - A) / LengthSquared;
//public bool IsAbove(Vector3 q) => Direction.Dot(q - Point) > 0; public bool IsAbove(Vector3 q) => ExtVector3.DotProduct(q - Point, Direction) > 0;
/// <summary> /// return the middle of X points (POINTS, NOT vector) /// </summary> public static Vector3 GetMiddleOfXPoint(Vector3[] arrayVect, bool barycenter = true) { if (arrayVect.Length == 0) { return(ExtVector3.GetNullVector()); } if (!barycenter) { Vector3 sum = Vector3.zero; for (int i = 0; i < arrayVect.Length; i++) { sum += arrayVect[i]; } return(sum / arrayVect.Length); } else { if (arrayVect.Length == 1) { return(arrayVect[0]); } float xMin = arrayVect[0].x; float yMin = arrayVect[0].y; float zMin = arrayVect[0].z; float xMax = arrayVect[0].x; float yMax = arrayVect[0].y; float zMax = arrayVect[0].z; for (int i = 1; i < arrayVect.Length; i++) { if (arrayVect[i].x < xMin) { xMin = arrayVect[i].x; } if (arrayVect[i].x > xMax) { xMax = arrayVect[i].x; } if (arrayVect[i].y < yMin) { yMin = arrayVect[i].y; } if (arrayVect[i].y > yMax) { yMax = arrayVect[i].y; } if (arrayVect[i].z < zMin) { zMin = arrayVect[i].z; } if (arrayVect[i].z > zMax) { zMax = arrayVect[i].z; } } Vector3 lastMiddle = new Vector3((xMin + xMax) / 2, (yMin + yMax) / 2, (zMin + zMax) / 2); return(lastMiddle); } }