public override NewBlendableTransform GetBlendableTransformOnCurrentFrame(int hkxBoneIndex) { var track = HkxBoneIndexToTransformTrackMap[hkxBoneIndex]; if (track == -1) { var skeleTransform = Skeleton.OriginalHavokSkeleton.Transforms[hkxBoneIndex]; NewBlendableTransform defaultBoneTransformation = new NewBlendableTransform(); defaultBoneTransformation.Scale.X = skeleTransform.Scale.Vector.X; defaultBoneTransformation.Scale.Y = skeleTransform.Scale.Vector.Y; defaultBoneTransformation.Scale.Z = skeleTransform.Scale.Vector.Z; defaultBoneTransformation.Rotation = new Quaternion( skeleTransform.Rotation.Vector.X, skeleTransform.Rotation.Vector.Y, skeleTransform.Rotation.Vector.Z, skeleTransform.Rotation.Vector.W); defaultBoneTransformation.Translation.X = skeleTransform.Position.Vector.X; defaultBoneTransformation.Translation.Y = skeleTransform.Position.Vector.Y; defaultBoneTransformation.Translation.Z = skeleTransform.Position.Vector.Z; return(defaultBoneTransformation); } float frame = (CurrentFrame % FrameCount) % NumFramesPerBlock; if (frame >= FrameCount - 1) { NewBlendableTransform currentFrame = GetTransformOnSpecificBlockAndFrame(track, block: CurrentBlock, frame: (float)Math.Floor(frame)); NewBlendableTransform nextFrame = GetTransformOnSpecificBlockAndFrame(track, block: 0, frame: 0); currentFrame = NewBlendableTransform.Lerp(frame % 1, currentFrame, nextFrame); return(currentFrame); } // Regular frame else { NewBlendableTransform currentFrame = GetTransformOnSpecificBlockAndFrame(track, block: CurrentBlock, frame); return(currentFrame); } }
public static NewBlendableTransform Lerp(float lerp, NewBlendableTransform a, NewBlendableTransform b) { float posX = Utils.Lerp(a.Translation.X, b.Translation.X, lerp); float posY = Utils.Lerp(a.Translation.Y, b.Translation.Y, lerp); float posZ = Utils.Lerp(a.Translation.Z, b.Translation.Z, lerp); float scaleX = Utils.Lerp(a.Scale.X, b.Scale.X, lerp); float scaleY = Utils.Lerp(a.Scale.Y, b.Scale.Y, lerp); float scaleZ = Utils.Lerp(a.Scale.Z, b.Scale.Z, lerp); float rotationX = Utils.Lerp(a.Rotation.X, b.Rotation.X, lerp); float rotationY = Utils.Lerp(a.Rotation.Y, b.Rotation.Y, lerp); float rotationZ = Utils.Lerp(a.Rotation.Z, b.Rotation.Z, lerp); float rotationW = Utils.Lerp(a.Rotation.W, b.Rotation.W, lerp); return(new NewBlendableTransform() { Translation = new Vector3(posX, posY, posZ), Scale = new Vector3(scaleX, scaleY, scaleZ), Rotation = new Quaternion(rotationX, rotationY, rotationZ, rotationW), }); }
private NewBlendableTransform GetTransformOnSpecificBlockAndFrame(int transformIndex, int block, float frame) { frame = (frame % FrameCount) % NumFramesPerBlock; NewBlendableTransform result = NewBlendableTransform.Identity; var track = Tracks[block][transformIndex]; var skeleTransform = Skeleton.OriginalHavokSkeleton.Transforms[TransformTrackIndexToHkxBoneMap[transformIndex]]; //result.Scale.X = track.SplineScale?.ChannelX == null // ? (IsAdditiveBlend ? 1 : track.StaticScale.X) : track.SplineScale.GetValueX(frame); //result.Scale.Y = track.SplineScale?.ChannelY == null // ? (IsAdditiveBlend ? 1 : track.StaticScale.Y) : track.SplineScale.GetValueY(frame); //result.Scale.Z = track.SplineScale?.ChannelZ == null // ? (IsAdditiveBlend ? 1 : track.StaticScale.Z) : track.SplineScale.GetValueZ(frame); if (track.SplineScale != null) { result.Scale.X = track.SplineScale.GetValueX(frame) ?? (IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.X); result.Scale.Y = track.SplineScale.GetValueY(frame) ?? (IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.Y); result.Scale.Z = track.SplineScale.GetValueZ(frame) ?? (IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.Z); } else { if (track.Mask.ScaleTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticX)) { result.Scale.X = track.StaticScale.X; } else { result.Scale.X = IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.X; } if (track.Mask.ScaleTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticY)) { result.Scale.Y = track.StaticScale.Y; } else { result.Scale.Y = IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.Y; } if (track.Mask.ScaleTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticZ)) { result.Scale.Z = track.StaticScale.Z; } else { result.Scale.Z = IsAdditiveBlend ? 1 : skeleTransform.Scale.Vector.Z; } } if (IsAdditiveBlend) { result.Scale.X *= skeleTransform.Scale.Vector.X; result.Scale.Y *= skeleTransform.Scale.Vector.Y; result.Scale.Z *= skeleTransform.Scale.Vector.Z; } //if (result.Scale.LengthSquared() > (Vector3.One * 1.1f).LengthSquared()) //{ // Console.WriteLine(":fatoof:"); //} if (track.SplineRotation != null)//track.HasSplineRotation) { result.Rotation = track.SplineRotation.GetValue(frame); } else if (track.HasStaticRotation) { // We actually need static rotation or Gael hands become unbent among others result.Rotation = track.StaticRotation; } else { //result.Rotation = IsAdditiveBlend ? Quaternion.Identity : new Quaternion( // skeleTransform.Rotation.Vector.X, // skeleTransform.Rotation.Vector.Y, // skeleTransform.Rotation.Vector.Z, // skeleTransform.Rotation.Vector.W); } if (IsAdditiveBlend) { result.Rotation = new Quaternion( skeleTransform.Rotation.Vector.X, skeleTransform.Rotation.Vector.Y, skeleTransform.Rotation.Vector.Z, skeleTransform.Rotation.Vector.W) * result.Rotation; } if (track.SplinePosition != null) { result.Translation.X = track.SplinePosition.GetValueX(frame) ?? (IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.X); result.Translation.Y = track.SplinePosition.GetValueY(frame) ?? (IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.Y); result.Translation.Z = track.SplinePosition.GetValueZ(frame) ?? (IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.Z); } else { if (track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticX)) { result.Translation.X = track.StaticPosition.X; } else { result.Translation.X = IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.X; } if (track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticY)) { result.Translation.Y = track.StaticPosition.Y; } else { result.Translation.Y = IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.Y; } if (track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticZ)) { result.Translation.Z = track.StaticPosition.Z; } else { result.Translation.Z = IsAdditiveBlend ? 0 : skeleTransform.Position.Vector.Z; } } //result.Translation.X = track.SplinePosition?.GetValueX(frame) ?? (IsAdditiveBlend ? 0 : track.StaticPosition.X); //result.Translation.Y = track.SplinePosition?.GetValueY(frame) ?? (IsAdditiveBlend ? 0 : track.StaticPosition.Y); //result.Translation.Z = track.SplinePosition?.GetValueZ(frame) ?? (IsAdditiveBlend ? 0 : track.StaticPosition.Z); //if (!IsAdditiveBlend && (!track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.SplineX) && // !track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticX))) //{ // result.Translation.X = skeleTransform.Position.Vector.X; //} //if (!IsAdditiveBlend && (!track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.SplineY) && // !track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticY))) //{ // result.Translation.Y = skeleTransform.Position.Vector.Y; //} //if (!IsAdditiveBlend && (!track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.SplineZ) && // !track.Mask.PositionTypes.Contains(Havok.SplineCompressedAnimation.FlagOffset.StaticZ))) //{ // result.Translation.Z = skeleTransform.Position.Vector.Z; //} if (IsAdditiveBlend) { result.Translation.X += skeleTransform.Position.Vector.X; result.Translation.Y += skeleTransform.Position.Vector.Y; result.Translation.Z += skeleTransform.Position.Vector.Z; } return(result); }