public override void Update(double deltaTimeInSeconds)
        {
            this.currentTime += deltaTimeInSeconds;
            this.CalcCurrentFrameIndex();

            var alpha = (float)((this.currentTime - this.wayPoints[currentFrame].Time) /
                                (this.wayPoints[currentFrame + 1].Time - this.wayPoints[currentFrame].Time));

            alpha = DigitExtensions.Clamp(alpha, 0f, 1f);

            var curPos  = this.wayPoints[currentFrame].Pos;
            var curTan  = this.wayPoints[currentFrame].Tangent;
            var curRot  = this.wayPoints[currentFrame].Rot;
            var nextPos = this.wayPoints[currentFrame + 1].Pos;
            var nextTan = this.wayPoints[currentFrame + 1].Tangent;
            var nextRot = this.wayPoints[currentFrame + 1].Rot;


            var newPosX = this.HermiteCurve(curPos.X, nextPos.X, curTan.X, nextTan.X, alpha);
            var newPosY = this.HermiteCurve(curPos.Y, nextPos.Y, curTan.Y, nextTan.Y, alpha);
            var newPosZ = this.HermiteCurve(curPos.Z, nextPos.Z, curTan.Z, nextTan.Z, alpha);
            var newQuat = SCNQuaternion.Slerp(curRot, nextRot, alpha);

            node.WorldPosition    = new SCNVector3(newPosX, newPosY, newPosZ);
            node.WorldOrientation = newQuat;

            // update child rigid bodies to percolate into physics
            if (this.Entity is GameObject entity)
            {
                if (entity.PhysicsNode?.PhysicsBody != null)
                {
                    entity.PhysicsNode.PhysicsBody.ResetTransform();
                }
            }
        }
Beispiel #2
0
        public void Apply(PhysicsNodeData nodeData, bool isHalfway)
        {
            if (this.PhysicsNode != null)
            {
                // if we're not alive, avoid applying physics updates.
                // this will allow objects on clients to get culled properly
                if (this.IsAlive)
                {
                    if (isHalfway)
                    {
                        this.PhysicsNode.WorldPosition = (nodeData.Position + this.PhysicsNode.WorldPosition) * 0.5f;
                        this.PhysicsNode.Orientation   = SCNQuaternion.Slerp(this.PhysicsNode.Orientation, nodeData.Orientation, 0.5f);
                    }
                    else
                    {
                        this.PhysicsNode.WorldPosition = nodeData.Position;
                        this.PhysicsNode.Orientation   = nodeData.Orientation;
                    }

                    if (this.PhysicsNode.PhysicsBody != null)
                    {
                        this.PhysicsNode.PhysicsBody.ResetTransform();
                        this.PhysicsNode.PhysicsBody.Velocity        = nodeData.Velocity;
                        this.PhysicsNode.PhysicsBody.AngularVelocity = nodeData.AngularVelocity;
                    }
                }
            }
        }
        /// <summary>
        /// Inch geometry back to original offset from rigid body
        /// </summary>
        private void UpdateSmooth(double deltaTime)
        {
            //  allow some motion up to a maximum offset
            var posDelta = this.parentOffPos - this.sourceOffPos;

            if (posDelta.Length > MaxCorrection)
            {
                posDelta = MaxCorrection * SCNVector3.Normalize(posDelta);
            }

            // lerp pos
            var newPos = this.sourceOffPos + posDelta;

            this.geometryNode.Position = newPos;

            // cap the max rotation that can show through
            var quatDelta = this.parentOffRot.Divide(this.sourceOffRot);

            quatDelta.ToAxisAngle(out SCNVector3 _, out float angle);

            if (angle > MaxRotation)
            {
                this.geometryNode.Orientation = SCNQuaternion.Slerp(this.sourceOffRot, this.parentOffRot, MaxRotation / angle);
            }
            else
            {
                this.geometryNode.Orientation = this.parentOffRot;
            }
        }
Beispiel #4
0
        public static SCNMatrix4 Interpolate(SCNMatrix4 scnm0, SCNMatrix4 scnmf, nfloat factor)
        {
            SCNVector4 p0 = scnm0.Row3;
            SCNVector4 pf = scnmf.Row3;

            var q0 = scnm0.ToQuaternion();
            var qf = scnmf.ToQuaternion();

            SCNVector4    pTmp = Lerp(p0, pf, factor);
            SCNQuaternion qTmp = SCNQuaternion.Slerp(q0, qf, (float)factor);
            SCNMatrix4    rTmp = qTmp.ToMatrix4();

            SCNMatrix4 transform = new SCNMatrix4(
                rTmp.M11, rTmp.M12, rTmp.M13, 0.0f,
                rTmp.M21, rTmp.M22, rTmp.M23, 0.0f,
                rTmp.M31, rTmp.M32, rTmp.M33, 0.0f,
                pTmp.X, pTmp.Y, pTmp.Z, 1.0f
                );

            return(transform);
        }