10 return { toFlip[1], toFlip[0], toFlip[2] };
19 static void RotateTowards(out
float result[4],
float from[4],
float to[4],
float maxDegreesDelta)
21 float num =
Math3D.QuatAngle(from, to);
22 if (
float.AlmostEqual(num, 0.0))
24 Math3D.QuatCopy(to, result);
28 float t =
Math.Min(1, maxDegreesDelta / num);
29 Math3D.QuatLerp(result, from, to, t);
40 vector diff = target - start;
41 float magnitude = diff.Length();
42 if (magnitude <= maxDistanceDelta || magnitude == 0)
45 return start + diff / magnitude * maxDistanceDelta;
58 for (
int i; i < 3; ++i)
75 for (
int i; i < 3; i++)
95 static void Extrapolate(
IEntity entity,
Physics physics,
vector netPosition,
vector netVelocityLinear,
float netTeleportDistance,
float netRotation[4],
vector netVelocityAngular,
float netTeleportAng,
float timeSinceLastTick,
float timeSlice,
float netTickInterval)
107 if (!physics || !physics.IsDynamic())
110 Math3D.QuatToMatrix(netRotation, currentMatrix);
112 currentMatrix[3] = netPosition;
120 vector projectedPos = netPosition + netVelocityLinear * timeSinceLastTick;
122 vector netVelocityAngularFlipped = GetFixedAxisVector(netVelocityAngular * timeSinceLastTick);
123 float projectedRotation[4];
124 float netVelocityAngularQuat[4];
125 netVelocityAngularFlipped.QuatFromAngles(netVelocityAngularQuat);
126 Math3D.QuatMultiply(projectedRotation, netRotation, netVelocityAngularQuat);
133 if (posError > netTeleportDistance)
140 if (rotError > netTeleportAng)
142 Math3D.QuatToMatrix(netRotation, currentMatrix);
148 float timeStep = timeSlice / netTickInterval;
149 float timeStepTick =
Math.Clamp(timeSlice / netTickInterval, 0, 1);
155 physics.SetVelocity(physics.GetVelocity() + (projectedPos -
position) * timeStepTick);
161 Math3D.QuatRotateTowards(outRot,
rotation, projectedRotation, (rotError * timeStep) *
Math.RAD2DEG);
162 Math3D.QuatToMatrix(outRot, currentMatrix);
169 Math3D.QuatMultiply(rotDiff, projectedRotation, rotInv);
171 angularVelocity = FixEulerVector180(angularVelocity) *
Math.DEG2RAD * timeStepTick;
172 angularVelocity += physics.GetAngularVelocity();
173 physics.SetAngularVelocity(angularVelocity);
188 return rayPos - rayVector * (
vector.Dot(rayPos - planePos, planeNormal) /
vector.Dot(rayVector, planeNormal));
196 static bool MatrixEqual(
vector matrixA[4],
vector matrixB[4])
198 return matrixA[3] == matrixB[3]
199 && matrixA[2] == matrixB[2]
200 && matrixA[1] == matrixB[1]
201 && matrixA[0] == matrixB[0];
208 static bool IsMatrixEmpty(
vector matrix[4])
210 return matrix[3] ==
vector.Zero
211 && matrix[2] ==
vector.Zero
212 && matrix[1] ==
vector.Zero
213 && matrix[0] ==
vector.Zero;
220 static bool IsMatrixIdentity(
vector matrix[4])
222 return matrix[3] ==
vector.Zero
223 && matrix[2] ==
vector.Forward
225 && matrix[0] ==
vector.Right;
239 Math.Min(vA[0], vB[0]),
240 Math.Min(vA[1], vB[1]),
241 Math.Min(vA[2], vB[2])
256 Math.Max(vA[0], vB[0]),
257 Math.Max(vA[1], vB[1]),
258 Math.Max(vA[2], vB[2])
267 static float GetDistanceFromSpline(notnull array<vector> points,
vector point)
269 int count = points.Count();
274 return vector.Distance(point, points[0]);
276 float tempDistanceSq;
277 vector segmentStart = points[0];
278 float minDistanceSq =
vector.DistanceSq(point, segmentStart);
280 foreach (
int i,
vector segmentEnd : points)
285 tempDistanceSq =
Math3D.PointLineSegmentDistanceSqr(point, segmentStart, segmentEnd);
286 if (tempDistanceSq < minDistanceSq)
287 minDistanceSq = tempDistanceSq;
289 segmentStart = segmentEnd;
292 return Math.Sqrt(minDistanceSq);
300 static float GetDistanceFromSplineXZ(notnull array<vector> points,
vector point)
302 int count = points.Count();
307 return vector.DistanceXZ(point, points[0]);
309 float tempDistanceSq;
310 vector segmentStart = points[0];
311 float minDistanceSq =
vector.DistanceSqXZ(point, segmentStart);
315 foreach (
int i,
vector segmentEnd : points)
322 tempDistanceSq =
Math3D.PointLineSegmentDistanceSqr(point, segmentStart, segmentEnd);
323 if (tempDistanceSq < minDistanceSq)
324 minDistanceSq = tempDistanceSq;
326 segmentStart = segmentEnd;
329 return Math.Sqrt(minDistanceSq);
338 static bool IsPointWithinSplineDistance(notnull array<vector> points,
vector point,
float distance)
340 int count = points.Count();
348 vector segmentStart = points[0];
350 foreach (
int i,
vector segmentEnd : points)
355 if (
Math3D.PointLineSegmentDistanceSqr(point, segmentStart, segmentEnd) <
distance)
358 segmentStart = segmentEnd;
370 static bool IsPointWithinSplineDistanceXZ(notnull array<vector> points,
vector point,
float distance)
372 int count = points.Count();
380 vector segmentStart = points[0];
384 foreach (
int i,
vector segmentEnd : points)
391 if (
Math3D.PointLineSegmentDistanceSqr(point, segmentStart, segmentEnd) <
distance)
394 segmentStart = segmentEnd;
412 static void QuatAngleAxis(
float angle,
vector axis, out
float quat[4])
415 float sin =
Math.Sin(angle);
418 quat[0] = axis[0] * sin;
419 quat[1] = axis[1] * sin;
420 quat[2] = axis[2] * sin;
421 quat[3] =
Math.Cos(angle);
431 vector xyz = { quat[0], quat[1], quat[2] };
432 vector t = 2.0 * (xyz * vec);
433 return vec + quat[3] * t + (xyz * t);
446 QuatAngleAxis(angle, axis, q);
447 result[3] = QuatMultiply(q, (transform[3] - pivot)) + pivot;
450 Math3D.MatrixToQuat(transform, qt);
451 Math3D.QuatMultiply(qt, q, qt);
452 Math3D.QuatToMatrix(qt, result);
463 Math3D.DirectionAndUpMatrix(
vector.Direction(source, destination).Normalized(), up.Normalized(), rotMat);
473 if (v.LengthSq() > magnitude * magnitude)
474 return v.Normalized() * magnitude;
487 if (normalizeVectors)
493 return { first[1] * second[2] - first[2] * second[1],
494 first[2] * second[0] - first[0] * second[2],
495 first[0] * second[1] - first[1] * second[0]};