internal TrajectoryModel(ref ArrayMemory memory, ref Binary binary) { // // Initialize attributes // this.binary = MemoryRef <Binary> .Create(ref binary); float sampleRate = binary.SampleRate; float timeHorizon = binary.TimeHorizon; int trajectoryLength = DurationToFrames(timeHorizon * 2.0f, sampleRate); trajectory = memory.CreateSlice <AffineTransform>(trajectoryLength); for (int i = 0; i < trajectoryLength; ++i) { trajectory[i] = AffineTransform.identity; } var accumulatedIdentity = AccumulatedTransform.Create( AffineTransform.identity, math.rcp(binary.SampleRate)); deltaSpaceTrajectory = memory.CreateSlice <AccumulatedTransform>(trajectoryLength * 2); for (int i = 0; i < trajectoryLength * 2; ++i) { deltaSpaceTrajectory[i] = accumulatedIdentity; } Assert.IsTrue(trajectoryLength == TrajectoryLength); }
internal void Update(AffineTransform worldRootTransform, AffineTransform deltaTransform, float deltaTime) { NativeSlice <AffineTransform> trajectory = Array; int trajectoryLength = TrajectoryLength; int halfTrajectoryLength = trajectoryLength / 2; // // Since the trajectory is relative to the world root transform // and the synthesizer is adding 'deltaTransform' we need // to account for this by inverse transforming the // character space trajectory transforms. // var inverseQ = math.normalize( Missing.conjugate(deltaTransform.q)); for (int i = halfTrajectoryLength; i < trajectoryLength; ++i) { var transform = trajectory[i]; transform.t = Missing.rotateVector( inverseQ, transform.t); transform.q = math.normalize( math.mul(inverseQ, transform.q)); trajectory[i] = transform; } // // Update past trajectory // for (int i = deltaSpaceTrajectory.Length - 1; i > 0; --i) { deltaSpaceTrajectory[i] = deltaSpaceTrajectory[i - 1]; } var accumulatedTransform = deltaSpaceTrajectory[1].transform * deltaTransform; accumulatedTransform.q = math.normalize(accumulatedTransform.q); deltaSpaceTrajectory[0] = AccumulatedTransform.Create( accumulatedTransform, deltaTime); var referenceTransform = deltaSpaceTrajectory[0].transform; float sampleTimeInSeconds = 0.0f; float inverseSampleRate = Missing.recip(Binary.SampleRate); int numTransforms = deltaSpaceTrajectory.Length; var sampler = SubSampler.Create(); for (int i = halfTrajectoryLength - 1; i >= 0; --i) { sampleTimeInSeconds += inverseSampleRate; var deltaTransformAtSampleRate = sampler.SampleAt(deltaSpaceTrajectory, sampleTimeInSeconds); trajectory[i] = referenceTransform.inverseTimes( deltaTransformAtSampleRate); } }