public void undoPrecedingTransform(SSSkeletalJointLocation parentLoc) { var parOrientInverse = parentLoc.orientation.Inverted (); orientation = Quaternion.Multiply (parOrientInverse, orientation); orientation.Normalize (); position = Vector3.Transform (position - parentLoc.position, parOrientInverse); }
public void applyPrecedingTransform(SSSkeletalJointLocation parentLoc) { position = parentLoc.position + Vector3.Transform (position, parentLoc.orientation); orientation = Quaternion.Multiply (parentLoc.orientation, orientation); orientation.Normalize (); }
public void applyPrecedingTransform(SSSkeletalJointLocation parentLoc) { position = parentLoc.position + Vector3.Transform(position, parentLoc.orientation); orientation = Quaternion.Multiply(parentLoc.orientation, orientation); orientation.Normalize(); }
public void undoPrecedingTransform(SSSkeletalJointLocation parentLoc) { var parOrientInverse = parentLoc.orientation.Inverted(); orientation = Quaternion.Multiply(parOrientInverse, orientation); orientation.Normalize(); position = Vector3.Transform(position - parentLoc.position, parOrientInverse); }
public SSSkeletalAnimation(int frameRate, SSSkeletalJoint[] jointInfo, SSSkeletalJointLocation[][] frames, SSAABB[] bounds = null) { _hierarchy = jointInfo; _frames = frames; _bounds = bounds; _frameRate = frameRate; }
public static SSSkeletalJointLocation interpolate( SSSkeletalJointLocation left, SSSkeletalJointLocation right, float blend) { SSSkeletalJointLocation ret; ret.position = Vector3.Lerp(left.position, right.position, blend); ret.orientation = Quaternion.Slerp (left.orientation, right.orientation, blend); return ret; }
private SSSkeletalAnimationMD5 readAnimation() { Match[] matches; // header seekEntry ("MD5Version", "10"); seekEntry ("commandline", SSMD5Parser._quotedStrRegex); matches = seekEntry ("numFrames", SSMD5Parser._uintRegex); var numFrames = Convert.ToInt32 (matches [1].Value); matches = seekEntry ("numJoints", SSMD5Parser._uintRegex); var numJoints = Convert.ToInt32 (matches [1].Value); matches = seekEntry ("frameRate", SSMD5Parser._uintRegex); var frameRate = Convert.ToInt32 (matches [1].Value); matches = seekEntry ("numAnimatedComponents", SSMD5Parser._uintRegex); int numAnimatedComponents = Convert.ToInt32 (matches [1].Value); var floatComponents = new float[numAnimatedComponents]; // hierarchy seekEntry ("hierarchy", "{"); var hierarchy = new SSSkeletalJoint[numJoints]; var flags = new byte[numJoints]; for (int j = 0; j < numJoints; ++j) { hierarchy [j] = readHierarchyEntry (out flags [j]); } seekEntry ("}"); // bounds seekEntry ("bounds", "{"); var bounds = new SSAABB[numFrames]; for (int f = 0; f < numFrames; ++f) { bounds [f] = readBounds (); } seekEntry ("}"); // base frame seekEntry ("baseframe", "{"); for (int j = 0; j < numJoints; ++j) { hierarchy[j].bindPoseLocation = readBaseFrame (); } seekEntry ("}"); // frames var frames = new SSSkeletalJointLocation[numFrames][]; for (int f = 0; f < numFrames; ++f) { matches = seekEntry ("frame", SSMD5Parser._uintRegex, "{"); int frameIdx = Convert.ToInt32 (matches [1].Value); frames [frameIdx] = readFrameJoints (flags, hierarchy, floatComponents); seekEntry ("}"); } return new SSSkeletalAnimationMD5 (frameRate, hierarchy, frames, bounds); }
public static SSSkeletalJointLocation interpolate( SSSkeletalJointLocation left, SSSkeletalJointLocation right, float blend) { SSSkeletalJointLocation ret; ret.position = Vector3.Lerp(left.position, right.position, blend); ret.orientation = Quaternion.Slerp(left.orientation, right.orientation, blend); return(ret); }
private SSSkeletalJointLocation[] readFrameJoints(byte[] jointFlags, SSSkeletalJoint[] jointInfos, float[] floatComponents) { seekFloats(floatComponents); var thisFrameLocations = new SSSkeletalJointLocation[jointInfos.Length]; int compIdx = 0; for (int j = 0; j < jointInfos.Length; ++j) { byte flags = jointFlags[j]; SSSkeletalJoint jointInfo = jointInfos [j]; SSSkeletalJointLocation loc = jointInfo.bindPoseLocation; if ((flags & (byte)LocationFlags.Tx) != 0) { loc.position.X = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Ty) != 0) { loc.position.Y = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Tz) != 0) { loc.position.Z = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qx) != 0) { loc.orientation.X = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qy) != 0) { loc.orientation.Y = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qz) != 0) { loc.orientation.Z = floatComponents [compIdx++]; } loc.computeQuatW(); #if false if (jointInfo.ParentIndex >= 0) // has a parent { SSSkeletalJointLocation parentLoc = thisFrameLocations [jointInfo.ParentIndex]; loc.Position = parentLoc.Position + Vector3.Transform(loc.Position, parentLoc.Orientation); loc.Orientation = Quaternion.Multiply(parentLoc.Orientation, loc.Orientation); loc.Orientation.Normalize(); } #endif thisFrameLocations[j] = loc; } return(thisFrameLocations); }
public override SSSkeletalJointLocation computeJointLocation(SSSkeletalJointRuntime joint) { if (_neutralViewDirty) { Quaternion precedingBindPoseOrient = Quaternion.Identity; for (var j = joint.parent; j != null; j = j.parent) { precedingBindPoseOrient = Quaternion.Multiply( joint.baseInfo.bindPoseLocation.orientation, precedingBindPoseOrient); } Quaternion precedingInverted = precedingBindPoseOrient.Inverted(); _neutralViewDirectionLocal = Vector3.Transform(_neutralViewDirectionBindPose, precedingInverted) .Normalized(); _neutralViewUpLocal = Vector3.Transform(_neutralViewUpBindPose, precedingInverted) .Normalized(); _neutralViewYLocal = Vector3.Transform( Vector3.Cross(_neutralViewDirectionBindPose, _neutralViewUpBindPose), precedingInverted) .Normalized(); _neutralViewDirty = false; } SSSkeletalJointLocation ret = new SSSkeletalJointLocation(); ret.position = jointPositionLocal; if (targetObject != null) { Vector3 targetPosInMesh = Vector3.Transform(targetObject.Pos, _hostObject.worldMat.Inverted()); Vector3 targetPosInLocal = targetPosInMesh; if (joint.parent != null) { targetPosInLocal = joint.parent.currentLocation.undoTransformTo(targetPosInLocal); } Vector3 targetDirLocal = targetPosInLocal - jointPositionLocal; Vector3 nvDir = new Vector3(); nvDir.X = Vector3.Dot(targetDirLocal, _neutralViewDirectionLocal); nvDir.Y = Vector3.Dot(targetDirLocal, _neutralViewYLocal); nvDir.Z = Vector3.Dot(targetDirLocal, _neutralViewUpLocal); float theta = -(float)Math.Atan2(nvDir.Y, nvDir.X); float phi = (float)Math.Atan2(nvDir.Z, nvDir.Xy.LengthFast); Quaternion neededRotation = Quaternion.FromAxisAngle(_neutralViewUpLocal, theta) * Quaternion.FromAxisAngle(_neutralViewYLocal, phi); ret.orientation = neutralViewOrientationLocal * neededRotation; } else { ret.orientation = neutralViewOrientationLocal; } return(ret); }
/// <summary> /// Retrieves a joint location for a particular timestamp; in joint-local coordinates /// </summary> public SSSkeletalJointLocation computeJointFrame(int jointIdx, float t) { int leftFrameIdx = (int)(t / frameDuration); SSSkeletalJointLocation leftJointFrame = _frames [leftFrameIdx] [jointIdx]; float remainder = t - ((float)leftFrameIdx * frameDuration); if (remainder == 0) { return(leftJointFrame); } else { SSSkeletalJointLocation rightJointFrame = _frames [leftFrameIdx + 1] [jointIdx]; return(SSSkeletalJointLocation.interpolate( leftJointFrame, rightJointFrame, remainder / frameDuration)); } }
public SSSkeletalJointLocation computeJointFrame(int jointIdx) { if (_currAnimation != null) { var loc = _currAnimation.computeJointFrame(jointIdx, _currT); if (_prevAnimation == null) { //GL.Color3 (1f, 0f, 0f); return(loc); } else { var prevTime = Math.Min(_prevT, _prevAnimation.totalDuration); var prevLoc = _prevAnimation.computeJointFrame(jointIdx, prevTime); #if PREV_PREV_FADE if (_prevPrevAnimation != null) { var prevPrevLoc = _prevPrevAnimation.ComputeJointFrame(jointIdx, _prevPrevT); var prevFade = _prevT / _prevTransitionTime; prevLoc = SSSkeletalJointLocation.Interpolate(prevPrevLoc, prevLoc, prevFade); } #endif var fadeInRatio = _currT / _transitionTime; GL.Color3(fadeInRatio, 1f - fadeInRatio, 0); return(SSSkeletalJointLocation.interpolate(prevLoc, loc, fadeInRatio)); } } else if (_prevAnimation != null) { //GL.Color3 (0f, 1f, 0f); return(_prevAnimation.computeJointFrame(jointIdx, _prevT)); } else { var errMsg = "Attempting to compute a joint frame location from an inactive channel."; System.Console.WriteLine(errMsg); throw new Exception(errMsg); } }
private SSSkeletalJointLocation _computeJointLocWithControllers( SSSkeletalJointRuntime joint, List <SSSkeletalChannelController> controllers, int controllerIdx) { var channel = controllers [controllerIdx]; if (channel.isActive(joint)) { var channelLoc = channel.computeJointLocation(joint); if (joint.parent != null) { channelLoc.applyPrecedingTransform(joint.parent.currentLocation); } if (!channel.interChannelFade || channel.interChannelFadeIndentisy() >= 1f || controllerIdx == 0) { return(channelLoc); } else { var fallbackLoc = _computeJointLocWithControllers(joint, controllers, controllerIdx - 1); return(SSSkeletalJointLocation.interpolate( fallbackLoc, channelLoc, channel.interChannelFadeIndentisy())); } } else { if (controllerIdx > 0) { return(_computeJointLocWithControllers(joint, controllers, controllerIdx - 1)); } else { throw new Exception("fell through without an active skeletal channel controller"); } } }
private SSSkeletalJointLocation[] readFrameJoints(byte[] jointFlags, SSSkeletalJoint[] jointInfos, float[] floatComponents) { seekFloats (floatComponents); var thisFrameLocations = new SSSkeletalJointLocation[jointInfos.Length]; int compIdx = 0; for (int j = 0; j < jointInfos.Length; ++j) { byte flags = jointFlags[j]; SSSkeletalJoint jointInfo = jointInfos [j]; SSSkeletalJointLocation loc = jointInfo.bindPoseLocation; if ((flags & (byte)LocationFlags.Tx) != 0) { loc.position.X = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Ty) != 0) { loc.position.Y = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Tz) != 0) { loc.position.Z = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qx) != 0) { loc.orientation.X = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qy) != 0) { loc.orientation.Y = floatComponents [compIdx++]; } if ((flags & (byte)LocationFlags.Qz) != 0) { loc.orientation.Z = floatComponents [compIdx++]; } loc.computeQuatW (); #if false if (jointInfo.ParentIndex >= 0) { // has a parent SSSkeletalJointLocation parentLoc = thisFrameLocations [jointInfo.ParentIndex]; loc.Position = parentLoc.Position + Vector3.Transform (loc.Position, parentLoc.Orientation); loc.Orientation = Quaternion.Multiply (parentLoc.Orientation, loc.Orientation); loc.Orientation.Normalize (); } #endif thisFrameLocations[j] = loc; } return thisFrameLocations; }
private SSSkeletalAnimationMD5 readAnimation() { Match[] matches; // header seekEntry("MD5Version", "10"); seekEntry("commandline", SSMD5Parser._quotedStrRegex); matches = seekEntry("numFrames", SSMD5Parser._uintRegex); var numFrames = Convert.ToInt32(matches [1].Value); matches = seekEntry("numJoints", SSMD5Parser._uintRegex); var numJoints = Convert.ToInt32(matches [1].Value); matches = seekEntry("frameRate", SSMD5Parser._uintRegex); var frameRate = Convert.ToInt32(matches [1].Value); matches = seekEntry("numAnimatedComponents", SSMD5Parser._uintRegex); int numAnimatedComponents = Convert.ToInt32(matches [1].Value); var floatComponents = new float[numAnimatedComponents]; // hierarchy seekEntry("hierarchy", "{"); var hierarchy = new SSSkeletalJoint[numJoints]; var flags = new byte[numJoints]; for (int j = 0; j < numJoints; ++j) { hierarchy [j] = readHierarchyEntry(out flags [j]); } seekEntry("}"); // bounds seekEntry("bounds", "{"); var bounds = new SSAABB[numFrames]; for (int f = 0; f < numFrames; ++f) { bounds [f] = readBounds(); } seekEntry("}"); // base frame seekEntry("baseframe", "{"); for (int j = 0; j < numJoints; ++j) { hierarchy[j].bindPoseLocation = readBaseFrame(); } seekEntry("}"); // frames var frames = new SSSkeletalJointLocation[numFrames][]; for (int f = 0; f < numFrames; ++f) { matches = seekEntry("frame", SSMD5Parser._uintRegex, "{"); int frameIdx = Convert.ToInt32(matches [1].Value); frames [frameIdx] = readFrameJoints(flags, hierarchy, floatComponents); seekEntry("}"); } return(new SSSkeletalAnimationMD5(frameRate, hierarchy, frames, bounds)); }
public SSSkeletalJointRuntime(SSSkeletalJoint baseInfo) { _baseInfo = baseInfo; currentLocation = _baseInfo.bindPoseLocation; }
public SSSkeletalAnimationMD5(int frameRate, SSSkeletalJoint[] jointInfo, SSSkeletalJointLocation[][] frames, SSAABB[] bounds) : base(frameRate, jointInfo, frames, bounds) { }
public override SSSkeletalJointLocation computeJointLocation(SSSkeletalJointRuntime joint) { if (_neutralViewDirty) { Quaternion precedingBindPoseOrient = Quaternion.Identity; for (var j = joint.parent; j != null; j = j.parent) { precedingBindPoseOrient = Quaternion.Multiply ( joint.baseInfo.bindPoseLocation.orientation, precedingBindPoseOrient); } Quaternion precedingInverted = precedingBindPoseOrient.Inverted (); _neutralViewDirectionLocal = Vector3.Transform (_neutralViewDirectionBindPose, precedingInverted) .Normalized(); _neutralViewUpLocal = Vector3.Transform (_neutralViewUpBindPose, precedingInverted) .Normalized(); _neutralViewYLocal = Vector3.Transform ( Vector3.Cross (_neutralViewDirectionBindPose, _neutralViewUpBindPose), precedingInverted) .Normalized(); _neutralViewDirty = false; } SSSkeletalJointLocation ret = new SSSkeletalJointLocation (); ret.position = jointPositionLocal; if (targetObject != null) { Vector3 targetPosInMesh = Vector3.Transform (targetObject.Pos, _hostObject.worldMat.Inverted()); Vector3 targetPosInLocal = targetPosInMesh; if (joint.parent != null) { targetPosInLocal = joint.parent.currentLocation.undoTransformTo (targetPosInLocal); } Vector3 targetDirLocal = targetPosInLocal - jointPositionLocal; Vector3 nvDir = new Vector3(); nvDir.X = Vector3.Dot (targetDirLocal, _neutralViewDirectionLocal); nvDir.Y = Vector3.Dot (targetDirLocal, _neutralViewYLocal); nvDir.Z = Vector3.Dot (targetDirLocal, _neutralViewUpLocal); float theta = -(float)Math.Atan2 (nvDir.Y, nvDir.X); float phi = (float)Math.Atan2 (nvDir.Z, nvDir.Xy.LengthFast); Quaternion neededRotation = Quaternion.FromAxisAngle (_neutralViewUpLocal, theta) * Quaternion.FromAxisAngle (_neutralViewYLocal, phi); ret.orientation = neutralViewOrientationLocal * neededRotation; } else { ret.orientation = neutralViewOrientationLocal; } return ret; }