public void SetMinMax(FixVec3 min, FixVec3 max) { _min = min; _max = max; UpdateFromMinMax(); }
public void Expand(FixVec3 amount) { _size += amount; _extents = _size / 2; _min = _center - _extents; _max = _center + _extents; }
public FixBounds(FixVec3 center, FixVec3 size) { _center = center; _extents = size / 2; _min = _center - _extents; _max = _center + _extents; _size = size; }
public FixVec3 Cross(FixVec3 rhs) { return(new FixVec3( Y * rhs.Z - Z * rhs.Y, Z * rhs.X - X * rhs.Z, X * rhs.Y - Y * rhs.X )); }
public static FixTrans3 MakeScale(FixVec3 scale) { return(new FixTrans3( scale.X, 0, 0, 0, 0, scale.Y, 0, 0, 0, 0, scale.Z, 0 )); }
public static FixTrans3 MakeTranslation(FixVec3 delta) { return(new FixTrans3( 1, 0, 0, delta.X, 0, 1, 0, delta.Y, 0, 0, 1, delta.Z )); }
// todo: move to quaternions public FixTrans3(FixVec3 position, FixVec3 scale, FixVec3 rotation) { this = MakeRotationX(rotation.X) .RotateY(rotation.Y) .RotateZ(rotation.Z) .Scale(scale) .Translate(position); }
public FixTrans3 Scale(FixVec3 scale) { return(new FixTrans3( M11 * scale.X, M12 * scale.X, M13 * scale.X, M14 * scale.X, M21 * scale.Y, M22 * scale.Y, M23 * scale.Y, M24 * scale.Y, M31 * scale.Z, M32 * scale.Z, M33 * scale.Z, M34 * scale.Z )); }
public FixTrans3 Translate(FixVec3 delta) { return(new FixTrans3( M11, M12, M13, M14 + delta.X, M21, M22, M23, M24 + delta.Y, M31, M32, M33, M34 + delta.Z )); }
public FixVec3 ClosestPoint(FixVec3 point) { // Clamp point to bounds Fix x = FixMath.Min(FixMath.Max(_min.X, point.X), _max.X); Fix y = FixMath.Min(FixMath.Max(_min.Y, point.Y), _max.Y); Fix z = FixMath.Min(FixMath.Max(_min.Z, point.Z), _max.Z); // Return clamped point return(new FixVec3(x, y, z)); }
/// <summary> /// Constructs a quaternion from a vector3. /// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles /// </summary> /// <param name="vector">The vector3 being converted.</param> public FixQuaternion(FixVec3 vector) { w = FixMath.Cos(vector.z / 2) * FixMath.Cos(vector.y / 2) * FixMath.Cos(vector.x / 2) + FixMath.Sin(vector.z / 2) * FixMath.Sin(vector.y / 2) * FixMath.Sin(vector.x / 2); x = FixMath.Cos(vector.z / 2) * FixMath.Cos(vector.y / 2) * FixMath.Sin(vector.x / 2) - FixMath.Sin(vector.z / 2) * FixMath.Sin(vector.y / 2) * FixMath.Cos(vector.x / 2); y = FixMath.Sin(vector.z / 2) * FixMath.Cos(vector.y / 2) * FixMath.Sin(vector.x / 2) + FixMath.Cos(vector.z / 2) * FixMath.Sin(vector.y / 2) * FixMath.Cos(vector.x / 2); z = FixMath.Sin(vector.z / 2) * FixMath.Cos(vector.y / 2) * FixMath.Cos(vector.x / 2) - FixMath.Cos(vector.z / 2) * FixMath.Sin(vector.y / 2) * FixMath.Sin(vector.x / 2); }
public void DecomposeTRSPosition(float tX, float tY, float tZ, float sX, float sY, float sZ, float rX, float rY, float rZ) { FixVec3 pos = new FixVec3((Fix)tX, (Fix)tY, (Fix)tZ); FixVec3 rotation = new FixVec3((Fix)rX, (Fix)rY, (Fix)rZ); FixVec3 scale = new FixVec3((Fix)sX, (Fix)sY, (Fix)sZ); FixTrans3 ft = new FixTrans3(pos, rotation, scale); Assert.AreEqual(ft.Position().X.raw, pos.X.raw); Assert.AreEqual(ft.Position().Y.raw, pos.Y.raw); Assert.AreEqual(ft.Position().Z.raw, pos.Z.raw); }
public void DecomposeTRSEulerAngle(float tX, float tY, float tZ, float sX, float sY, float sZ, float rX, float rY, float rZ) { FixVec3 pos = new FixVec3((Fix)tX, (Fix)tY, (Fix)tZ); FixVec3 rotation = new FixVec3((Fix)rX, (Fix)rY, (Fix)rZ); FixVec3 scale = new FixVec3((Fix)sX, (Fix)sY, (Fix)sZ); FixTrans3 ft = new FixTrans3(pos, rotation, scale); Assert.AreEqual(ft.EulerAngle().x.raw, rotation.x.raw); Assert.AreEqual(ft.EulerAngle().y.raw, rotation.y.raw); Assert.AreEqual(ft.EulerAngle().z.raw, rotation.z.raw); }
public bool Contains(FixVec3 point) { if ((point.X < xMin) || (point.X > xMax) || (point.Y < yMin) || (point.Y > yMax)) { return(false); } return(true); }
public void EulerForwardBack(int x, int y, int z) { FixQuaternion quat = new FixQuaternion(new FixVec3(x, y, z)); FixVec3 fv = FixQuaternion.ToEuler(quat); FixQuaternion final = new FixQuaternion(fv); Assert.AreEqual(final.x.raw, quat.x.raw); Assert.AreEqual(final.y.raw, quat.y.raw); Assert.AreEqual(final.z.raw, quat.z.raw); Assert.AreEqual(final.w.raw, quat.w.raw); }
public bool Contains(FixVec3 point) { if ((point.X < _min.X) || (point.X > _max.X) || (point.Y < _min.Y) || (point.Y > _max.Y) || (point.Z < _min.Z) || (point.Z > _max.Z)) { return(false); } return(true); }
/// <summary> /// we have to use a bit of trickery in this one. The rays must be cast from a small distance inside of our /// collider (skinWidth) to avoid zero distance rays which will get the wrong normal. Because of this small offset /// we have to increase the ray distance skinWidth then remember to remove skinWidth from deltaMovement before /// actually moving the player /// </summary> void moveHorizontally(ref FixVec3 deltaMovement) { var isGoingRight = deltaMovement.x > 0; var rayDistance = FixMath.Abs(deltaMovement.x) + _skinWidth; var rayDirection = isGoingRight ? FixVec2.right : -FixVec2.right; var initialRayOrigin = isGoingRight ? _raycastOrigins.bottomRight : _raycastOrigins.bottomLeft; for (var i = 0; i < totalHorizontalRays; i++) { var ray = new FixVec2(initialRayOrigin.x, initialRayOrigin.y + i * _verticalDistanceBetweenRays); // if we are grounded we will include oneWayPlatforms only on the first ray (the bottom one). this will allow us to // walk up sloped oneWayPlatforms. } }
/// <summary> /// handles adjusting deltaMovement if we are going up a slope. /// </summary> /// <returns><c>true</c>, if horizontal slope was handled, <c>false</c> otherwise.</returns> /// <param name="deltaMovement">Delta movement.</param> /// <param name="angle">Angle.</param> bool handleHorizontalSlope(ref FixVec3 deltaMovement, Fix angle) { // disregard 90 degree angles (walls) if (FixMath.Round(angle) == 90) { return(false); } if (angle < slopeLimit) { } else // too steep. get out of here { deltaMovement.x = Fix.zero; } return(true); }
public void Encapsulate(FixBounds other) { Fix x; Fix y; Fix z; // Expand min x = FixMath.Min(_min.X, other._min.X); y = FixMath.Min(_min.Y, other._min.Y); z = FixMath.Min(_min.Z, other._min.Z); _min = new FixVec3(x, y, z); // Expand max x = FixMath.Max(_max.X, other._max.X); y = FixMath.Max(_max.Y, other._max.Y); z = FixMath.Max(_max.Z, other._max.Z); _max = new FixVec3(x, y, z); // Update other values UpdateFromMinMax(); }
void moveVertically(ref FixVec3 deltaMovement) { var isGoingUp = deltaMovement.y > 0; var rayDistance = FixMath.Abs(deltaMovement.y) + _skinWidth; var rayDirection = isGoingUp ? FixVec2.up : -FixVec2.up; var initialRayOrigin = isGoingUp ? _raycastOrigins.topLeft : _raycastOrigins.bottomLeft; // apply our horizontal deltaMovement here so that we do our raycast from the actual position we would be in if we had moved initialRayOrigin.x += deltaMovement.x; // if we are moving up, we should ignore the layers in oneWayPlatformMask var mask = platformMask; if ((isGoingUp && !collisionState.wasGroundedLastFrame) || ignoreOneWayPlatformsThisFrame) { mask &= ~oneWayPlatformMask; } for (var i = 0; i < totalVerticalRays; i++) { var ray = new FixVec2(initialRayOrigin.x + i * _horizontalDistanceBetweenRays, initialRayOrigin.y); } }
public Fix SqrDistance(FixVec3 point) { FixVec3 clampedPoint = ClosestPoint(point); return((point - clampedPoint).GetSqrMagnitude()); }
public static FixTrans3 MakeRotation(FixVec3 degrees) { return(MakeRotationX(degrees.X) .RotateY(degrees.Y) .RotateZ(degrees.Z)); }
public FixVec3 Apply(FixVec3 vec) { return(this * vec); }
public FixTrans3 Rotate(FixVec3 degrees) { return(MakeRotation(degrees)); }
/// <summary> /// checks the center point under the BoxCollider2D for a slope. If it finds one then the deltaMovement is adjusted so that /// the player stays grounded and the slopeSpeedModifier is taken into account to speed up movement. /// </summary> /// <param name="deltaMovement">Delta movement.</param> private void handleVerticalSlope(ref FixVec3 deltaMovement) { }
public Fix Dot(FixVec3 rhs) { return(X * rhs.X + Y * rhs.Y + Z * rhs.Z); }
public FixRay(FixVec3 origin, FixVec3 direction) { _origin = origin; _direction = direction.Normalize(); }
private void UpdateFromMinMax() { _size = _max - _min; _extents = _size / 2; _center = _min + extents; }
/// <summary> /// attempts to move the character to position + deltaMovement. Any colliders in the way will cause the movement to /// stop when run into. /// </summary> /// <param name="deltaMovement">Delta movement.</param> public void move(FixVec3 deltaMovement) { // save off our current grounded state which we will use for wasGroundedLastFrame and becameGroundedThisFrame collisionState.wasGroundedLastFrame = collisionState.below; // clear our state collisionState.reset(); _raycastHitsThisFrame.Clear(); _isGoingUpSlope = false; primeRaycastOrigins(); // first, we check for a slope below us before moving // only check slopes if we are going down and grounded if (deltaMovement.y < Fix.zero && collisionState.wasGroundedLastFrame) { handleVerticalSlope(ref deltaMovement); } // now we check movement in the horizontal dir if (deltaMovement.x != Fix.zero) { moveHorizontally(ref deltaMovement); } // next, check movement in the vertical dir if (deltaMovement.y != Fix.zero) { moveVertically(ref deltaMovement); } // move then update our state deltaMovement.z = 0; tfTransform.Position += deltaMovement; // only calculate velocity if we have a non-zero deltaTime if (Time.deltaTime > 0f) { velocity = deltaMovement / (Fix)Time.deltaTime; } // set our becameGrounded state based on the previous and current collision state if (!collisionState.wasGroundedLastFrame && collisionState.below) { collisionState.becameGroundedThisFrame = true; } // if we are going up a slope we artificially set a y velocity so we need to zero it out here if (_isGoingUpSlope) { velocity.y = 0; } // send off the collision events if we have a listener if (onControllerCollidedEvent != null) { for (var i = 0; i < _raycastHitsThisFrame.Count; i++) { onControllerCollidedEvent(_raycastHitsThisFrame[i]); } } ignoreOneWayPlatformsThisFrame = false; }
// TODO - ED: Test // Source: https://github.com/erich666/GraphicsGems/blob/master/gems/RayBox.c public bool IntersectRay(FixRay ray, out Fix distance) { int whichPlane; bool inside = true; Quadrant[] quadrant = new Quadrant[3]; Fix[] maxT = new Fix[3]; Fix[] candidatePlane = new Fix[3]; Fix[] coord = new Fix[3]; FixVec3 intersection; Fix[] minB = { _min.X, _min.Y, _min.Z }; Fix[] maxB = { _max.X, _max.Y, _max.Z }; Fix[] rayOrigin = { ray.origin.X, ray.origin.Y, ray.origin.Z }; Fix[] rayDirection = { ray.direction.X, ray.direction.Y, ray.direction.Z }; // Find candidate planes; this loop can be avoided if // rays cast all from the eye(assume perpsective view). for (int i = 0; i < 3; i++) { if (rayOrigin[i] < minB[i]) { quadrant[i] = Quadrant.LEFT; candidatePlane[i] = minB[i]; inside = false; } else if (rayOrigin[i] > maxB[i]) { quadrant[i] = Quadrant.RIGHT; candidatePlane[i] = maxB[i]; inside = false; } else { quadrant[i] = Quadrant.MIDDLE; } } // Ray origin inside bounding box. if (inside) { distance = Fix.Zero; return(true); } // Calculate T distances to candidate planes. for (int i = 0; i < 3; i++) { if (quadrant[i] != Quadrant.MIDDLE && rayDirection[i] != Fix.Zero) { maxT[i] = (candidatePlane[i] - rayOrigin[i]) / rayDirection[i]; } else { maxT[i] = -Fix.One; } } // Get largest of the maxT's for final choice of intersection. whichPlane = 0; for (int i = 1; i < 3; i++) { if (maxT[whichPlane] < maxT[i]) { whichPlane = i; } } // Check final candidate actually inside box. if (maxT[whichPlane] < Fix.Zero) { distance = Fix.Zero; return(false); } for (int i = 0; i < 3; i++) { if (whichPlane != i) { coord[i] = rayOrigin[i] + maxT[whichPlane] * rayDirection[i]; if (coord[i] < minB[i] || coord[i] > maxB[i]) { distance = Fix.Zero; return(false); } } else { coord[i] = candidatePlane[i]; } } intersection = new FixVec3(coord[0], coord[1], coord[2]); distance = (intersection - ray.origin).GetMagnitude(); return(true); }