private static float4 Sample2(sampler tex, float4 coords, float polar) { float4 tex1 = tex.SampleLevel(coords.xy); float4 tex2 = tex.SampleLevel(coords.zw); return(_lerp(tex1, tex2, polar)); }
internal List <float> GetTimesForBone(string bone, library_visual_scenes lvs) { List <float> ret = new List <float>(); foreach (channel chan in mChannels) { //extract the node name and address int sidx = chan.target.IndexOf('/'); string sid = chan.target.Substring(0, sidx); //ok this is tricky, the spec says that the <source> //referenced by the input with the JOINT semantic //should contain a <Name_array> that contains sids //to identify the joint nodes. sids are used instead //of IDREFs to allow a skin controller to be instantiated //multiple times, where each instance can be animated //independently. // //So max's default collada exporter doesn't even give the //bones sids at all, and the other one whose name escapes //me gives the bones sids, but then the address element //says Name (note the case), so I guess you need to try //to match via sid first and if that fails, use name? node n = AnimForm.LookUpNode(lvs, sid); if (n == null) { continue; } if (bone != n.name) { continue; } //grab sampler key string sampKey = chan.source; //strip # sampKey = sampKey.Substring(1); sampler samp = mSamplers[sampKey]; string srcInp = GetSourceForSemantic(samp, "INPUT"); float_array srcTimes = mSources[srcInp].Item as float_array; foreach (float time in srcTimes.Values) { float t = time; if (ret.Contains(t)) { continue; } ret.Add(t); } } return(ret); }
private static float4 SampleSmooth(sampler tex, float2 coord, float2 size) { float2 pix = coord * size; float2 sub = _floor(pix - 0.5f) + 0.5f; float2 f = pix - sub; f = _smoothstep(_float2(0.0f, 0.0f), _float2(1.0f, 1.0f), f); return(tex.SampleLevel((sub + f) / size)); }
string GetSourceForSemantic(sampler samp, string sem) { string srcInp = ""; foreach (InputLocal inp in samp.input) { if (inp.semantic == sem) { srcInp = inp.source.Substring(1); } } return(srcInp); }
private static bool PrepareTexture(Texture texture, bool repX, bool repY, ref sampler sam) { sam.set = false; #if UNITY_EDITOR SgtHelper.MakeTextureReadable(texture); #endif if (texture != null && texture is Texture2D) { sam.set = true; sam.tex = (Texture2D)texture; sam.repX = repX; sam.repY = repY; sam.w = 0.5f / texture.width; sam.h = 0.5f / texture.height; } return(sam.set); }
public SubAnimation(animation anim) { foreach (object anObj in anim.Items) { if (anObj is source) { source src = anObj as source; mSources.Add(src.id, src); } else if (anObj is sampler) { sampler samp = anObj as sampler; mSamplers.Add(samp.id, samp); } else if (anObj is channel) { channel chan = anObj as channel; mChannels.Add(chan); } } }
private void ImportSampler() { sampler sampler = null; foreach (var item in Animation.Items) { if (item is sampler) { sampler = item as sampler; break; } } if (sampler == null) { throw new ParsingException("Animation " + Animation.id + " has no sampler!"); } ColladaSource inputSource = null, outputSource = null, interpolationSource = null; foreach (var input in sampler.input) { if (input.source[0] != '#') { throw new ParsingException("Only ID references are supported for animation input sources"); } ColladaSource source; if (!Sources.TryGetValue(input.source.Substring(1), out source)) { throw new ParsingException("Animation sampler " + input.semantic + " references nonexistent source: " + input.source); } switch (input.semantic) { case "INPUT": inputSource = source; break; case "OUTPUT": outputSource = source; break; case "INTERPOLATION": interpolationSource = source; break; default: break; } } if (inputSource == null || outputSource == null || interpolationSource == null) { throw new ParsingException("Animation " + Animation.id + " must have an INPUT, OUTPUT and INTERPOLATION sampler input!"); } if (!inputSource.FloatParams.TryGetValue("TIME", out Times)) { Times = inputSource.FloatParams.Values.SingleOrDefault(); } if (Times == null) { throw new ParsingException("Animation " + Animation.id + " INPUT must have a TIME parameter!"); } if (!outputSource.MatrixParams.TryGetValue("TRANSFORM", out Transforms)) { Transforms = outputSource.MatrixParams.Values.SingleOrDefault(); } if (Transforms == null) { throw new ParsingException("Animation " + Animation.id + " OUTPUT must have a TRANSFORM parameter!"); } if (Transforms.Count != Times.Count) { throw new ParsingException("Animation " + Animation.id + " has different time and transform counts!"); } for (var i = 0; i < Transforms.Count; i++) { var m = Transforms[i]; m.Transpose(); Transforms[i] = m; } }
protected void CreateChannel(List <object> listAnimationObjects, uint caseIndex, string sData, string sDataType, string sTarget, List <double> lValues) { string sTime = string.Format("sTime_{0}_ID", caseIndex); string sInterp = string.Format("sInterp_{0}_ID", caseIndex); // source source source_ = new source() { id = string.Format("sValue_{0}_{1}_ID", caseIndex, sData), name = string.Format("sValue_{0}_{1}", caseIndex, sData), Item = new float_array() { id = string.Format("fa_{0}_{1}_ID", caseIndex, sData), count = (ulong)lValues.Count, Values = lValues.ToArray() }, technique_common = new sourceTechnique_common() { accessor = new accessor() { source = string.Format("#fa_{0}_{1}_ID", caseIndex, sData), count = (ulong)lValues.Count, stride = 1, param = new param[] { new param() { name = sDataType, type = "float" } } } } }; listAnimationObjects.Add(source_); // sampler sampler sampler_ = new sampler() { id = string.Format("sampler_{0}_{1}_ID", caseIndex, sData), input = new InputLocal[] { new InputLocal() { semantic = "INPUT", source = "#" + sTime }, new InputLocal() { semantic = "OUTPUT", source = "#" + source_.id }, new InputLocal() { semantic = "INTERPOLATION", source = "#" + sInterp } } }; listAnimationObjects.Add(sampler_); // channel channel channel_ = new channel() { source = "#" + sampler_.id, target = sTarget }; listAnimationObjects.Add(channel_); }
public List <animation> ExportKeyframeTrack(TransformTrack transformTrack, string name, string target) { var track = transformTrack.ToKeyframes(); track.MergeAdjacentFrames(); track.InterpolateFrames(); var anims = new List <animation>(); var inputs = new List <InputLocal>(); var outputs = new List <float>(track.Keyframes.Count * 16); foreach (var keyframe in track.Keyframes.Values) { var transform = keyframe.ToTransform().ToMatrix4(); transform.Transpose(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(track.Keyframes.Count); for (int i = 0; i < track.Keyframes.Count; i++) { interpolations.Add("LINEAR"); } var knots = new List <float>(track.Keyframes.Count); foreach (var keyframe in track.Keyframes) { knots.Add(keyframe.Key); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (track.Keyframes.Count == 1) { knots.Add(transformTrack.ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "INTERPOLATION" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); return(anims); }
public List <animation> ExportTransform(IList <Keyframe> keyframes, string name, string target) { var anims = new List <animation>(); var inputs = new List <InputLocal>(); var outputs = new List <float>(keyframes.Count * 16); foreach (var keyframe in keyframes) { var transform = Matrix4.Identity; if (keyframe.hasRotation) { transform *= Matrix4.CreateFromQuaternion(keyframe.rotation.Inverted()); } if (keyframe.hasScaleShear) { var scaleShear = Matrix4.Identity; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { scaleShear[i, j] = keyframe.scaleShear[i, j]; } } transform *= scaleShear; } if (keyframe.hasTranslation) { transform[0, 3] += keyframe.translation[0]; transform[1, 3] += keyframe.translation[1]; transform[2, 3] += keyframe.translation[2]; } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(keyframes.Count); for (int i = 0; i < keyframes.Count; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } var knots = new List <float>(keyframes.Count); foreach (var keyframe in keyframes) { knots.Add(keyframe.time); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (keyframes.Count == 1) { knots.Add(ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "INTERPOLATION" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); return(anims); }
internal Animation.KeyPartsUsed SetKeys(string bone, List <float> times, List <MeshLib.KeyFrame> keys, library_visual_scenes scenes, List <MeshLib.KeyFrame> axisAngleKeys) { Animation.KeyPartsUsed ret = 0; foreach (channel chan in mChannels) { //extract the node name and address int sidx = chan.target.IndexOf('/'); string sid = chan.target.Substring(0, sidx); node n = AnimForm.LookUpNode(scenes, sid); if (n == null) { continue; } if (bone != n.name) { continue; } //grab sampler key string sampKey = chan.source; //strip # sampKey = sampKey.Substring(1); sampler samp = mSamplers[sampKey]; string srcInp = GetSourceForSemantic(samp, "INPUT"); string srcOut = GetSourceForSemantic(samp, "OUTPUT"); string srcC1 = GetSourceForSemantic(samp, "IN_TANGENT"); string srcC2 = GetSourceForSemantic(samp, "OUT_TANGENT"); float_array chanTimes = mSources[srcInp].Item as float_array; float_array chanValues = mSources[srcOut].Item as float_array; List <float> outValues = new List <float>(); int numChanKeys = chanValues.Values.Length; numChanKeys /= (int)mSources[srcOut].technique_common.accessor.stride; Debug.Assert(numChanKeys == (int)chanTimes.count); //grab values for this channel //along the overall list of times for (int tidx = 0; tidx < times.Count; tidx++) { outValues.AddRange(LerpValue(times[tidx], chanTimes, chanValues, (int)mSources[srcOut].technique_common.accessor.stride)); } int slashIndex = chan.target.IndexOf("/"); string nodeID = chan.target.Substring(0, slashIndex); string nodeElement = chan.target.Substring(slashIndex + 1); //see if the element has an additional address string addr = null; int dotIdx = nodeElement.IndexOf('.'); if (dotIdx != -1) { addr = nodeElement.Substring(dotIdx + 1); nodeElement = nodeElement.Substring(0, dotIdx); } node targeted = AnimForm.LookUpNode(scenes, nodeID); int idx = AnimForm.GetNodeItemIndex(targeted, nodeElement); if (idx == -1) { continue; //bad anim stuffs? } if (targeted.ItemsElementName[idx] == ItemsChoiceType2.lookat) { Debug.Assert(false); //haven't dealt with this one yet } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.matrix) { //this doesn't really work yet List <Matrix> mats = AnimForm.GetMatrixListFromFloatList(outValues); for (int v = 0; v < mats.Count; v++) { mats[v].Decompose(out keys[v].mScale, out keys[v].mRotation, out keys[v].mPosition); } ret |= Animation.KeyPartsUsed.All; } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.rotate) { if (addr == null) { //I'm guessing these would be true quaternions //I don't really support that, as I store the //usual axis angle stuff I've seen in a quaternion //and then later fix it up to be a real quaternion Debug.Assert(false); } else if (addr == "ANGLE") { Debug.Assert(targeted.Items[idx] is rotate); rotate rot = targeted.Items[idx] as rotate; if (rot.Values[0] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.X = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateX; } else if (rot.Values[1] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.Y = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateY; } else if (rot.Values[2] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.Z = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateZ; } else { Debug.Assert(false); //broken! } } } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.scale) { if (addr == null) { //I haven't seen this happen, but I'm guessing it //would be vector3s for (int v = 0; v < outValues.Count; v += 3) { keys[v / 3].mScale.X = outValues[v]; keys[v / 3].mScale.Y = outValues[v + 1]; keys[v / 3].mScale.Z = outValues[v + 2]; } ret |= Animation.KeyPartsUsed.ScaleX; ret |= Animation.KeyPartsUsed.ScaleY; ret |= Animation.KeyPartsUsed.ScaleZ; } else if (addr == "X") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.X = val; } ret |= Animation.KeyPartsUsed.ScaleX; } else if (addr == "Y") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.Y = val; } ret |= Animation.KeyPartsUsed.ScaleY; } else if (addr == "Z") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.Z = val; } ret |= Animation.KeyPartsUsed.ScaleZ; } } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.skew) { Debug.Assert(false); //haven't dealt with this one yet } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.translate) { if (addr == null) { //the values are vector3s in this case for (int v = 0; v < outValues.Count; v += 3) { keys[v / 3].mPosition.X = outValues[v]; keys[v / 3].mPosition.Y = outValues[v + 1]; keys[v / 3].mPosition.Z = outValues[v + 2]; } ret |= Animation.KeyPartsUsed.TranslateX; ret |= Animation.KeyPartsUsed.TranslateY; ret |= Animation.KeyPartsUsed.TranslateZ; } else if (addr == "X") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.X = val; } ret |= Animation.KeyPartsUsed.TranslateX; } else if (addr == "Y") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.Y = val; } ret |= Animation.KeyPartsUsed.TranslateY; } else if (addr == "Z") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.Z = val; } ret |= Animation.KeyPartsUsed.TranslateZ; } } } return(ret); }
public List <animation> ExportTransform(string name, string target) { var anims = new List <animation>(); if (NumKnots() > 0) { var inputs = new List <InputLocal>(); var numKnots = NumKnots(); var knots = GetKnots(); var outputs = new List <float>(knots.Count * 16); var quats = GetQuaternions(); foreach (var rotation in quats) { var transform = Matrix4.CreateFromQuaternion(rotation); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(numKnots); for (int i = 0; i < numKnots; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (numKnots == 1) { knots.Add(ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); } return(anims); }
public animation ExportChannel(string name, string target, string paramName, int coordinate, bool isRotation) { var inputs = new List <InputLocal>(); var numKnots = NumKnots(); var knots = GetKnots(); var outputs = ExportChannelControlData(coordinate, isRotation); var interpolations = new List <string>(numKnots); for (int i = 0; i < numKnots; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (numKnots == 1) { knots.Add(ParentAnimation.Duration); outputs.Add(outputs[0]); interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { paramName }, outputs.ToArray()); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); return(animation); }