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); }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //turn this on for help with leaky stuff //Configuration.EnableObjectTracking =true; GraphicsDevice gd = new GraphicsDevice("Collada Conversion Tool", FeatureLevel.Level_9_3, 0.1f, 3000f); //save renderform position gd.RendForm.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "MainWindowPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); gd.RendForm.Location = Settings.Default.MainWindowPos; SharedForms.ShaderCompileHelper.mTitle = "Compiling Shaders..."; StuffKeeper sk = new StuffKeeper(); sk.eCompileNeeded += SharedForms.ShaderCompileHelper.CompileNeededHandler; sk.eCompileDone += SharedForms.ShaderCompileHelper.CompileDoneHandler; sk.Init(gd, "."); MatLib matLib = new MatLib(gd, sk); matLib.InitCelShading(1); matLib.GenerateCelTexturePreset(gd.GD, gd.GD.FeatureLevel == FeatureLevel.Level_9_3, false, 0); matLib.SetCelTexture(0); PlayerSteering pSteering = SetUpSteering(); Input inp = SetUpInput(); Random rand = new Random(); CommonPrims comPrims = new CommonPrims(gd, sk); bool bMouseLookOn = false; //set up post processing module PostProcess post = new PostProcess(gd, matLib, "Post.fx"); EventHandler actHandler = new EventHandler( delegate(object s, EventArgs ea) { inp.ClearInputs(); }); EventHandler <EventArgs> deActHandler = new EventHandler <EventArgs>( delegate(object s, EventArgs ea) { gd.SetCapture(false); bMouseLookOn = false; }); gd.RendForm.Activated += actHandler; gd.RendForm.AppDeactivated += deActHandler; int resx = gd.RendForm.ClientRectangle.Width; int resy = gd.RendForm.ClientRectangle.Height; AnimForm ss = SetUpForms(gd.GD, matLib, sk, comPrims); Vector3 pos = Vector3.One * 5f; Vector3 lightDir = -Vector3.UnitY; UpdateTimer time = new UpdateTimer(true, false); time.SetFixedTimeStepSeconds(1f / 60f); //60fps update rate time.SetMaxDeltaSeconds(MaxTimeDelta); List <Input.InputAction> acts = new List <Input.InputAction>(); RenderLoop.Run(gd.RendForm, () => { if (!gd.RendForm.Focused) { Thread.Sleep(33); } gd.CheckResize(); if (bMouseLookOn && gd.RendForm.Focused) { gd.ResetCursorPos(); } //Clear views gd.ClearViews(); time.Stamp(); while (time.GetUpdateDeltaSeconds() > 0f) { acts = UpdateInput(inp, gd, time.GetUpdateDeltaSeconds(), ref bMouseLookOn); if (!gd.RendForm.Focused) { acts.Clear(); bMouseLookOn = false; gd.SetCapture(false); inp.UnMapAxisAction(Input.MoveAxis.MouseYAxis); inp.UnMapAxisAction(Input.MoveAxis.MouseXAxis); } Vector3 deltaMove = pSteering.Update(pos, gd.GCam.Forward, gd.GCam.Left, gd.GCam.Up, acts); deltaMove *= 200f; pos -= deltaMove; ChangeLight(acts, ref lightDir); time.UpdateDone(); } //light direction is backwards now for some strange reason matLib.SetParameterForAll("mLightDirection", -lightDir); gd.GCam.Update(pos, pSteering.Pitch, pSteering.Yaw, pSteering.Roll); matLib.UpdateWVP(Matrix.Identity, gd.GCam.View, gd.GCam.Projection, gd.GCam.Position); comPrims.Update(gd.GCam, lightDir); ss.RenderUpdate(time.GetRenderUpdateDeltaSeconds()); post.SetTargets(gd, "BackColor", "BackDepth"); post.ClearTarget(gd, "BackColor", Color.CornflowerBlue); post.ClearDepth(gd, "BackDepth"); ss.Render(gd.DC); if (ss.GetDrawAxis()) { comPrims.DrawAxis(gd.DC); } if (ss.GetDrawBox()) { comPrims.DrawBox(gd.DC, Matrix.Identity); } if (ss.GetDrawSphere()) { comPrims.DrawSphere(gd.DC, Matrix.Identity); } gd.Present(); acts.Clear(); }, true); //true here is slow but needed for winforms events Settings.Default.Save(); gd.RendForm.Activated -= actHandler; gd.RendForm.AppDeactivated -= deActHandler; comPrims.FreeAll(); inp.FreeAll(); post.FreeAll(gd); matLib.FreeAll(); sk.eCompileDone -= SharedForms.ShaderCompileHelper.CompileDoneHandler; sk.eCompileNeeded -= SharedForms.ShaderCompileHelper.CompileNeededHandler; sk.FreeAll(); //Release all resources gd.ReleaseAll(); }
static AnimForm SetUpForms(Device gd, MatLib matLib, StuffKeeper sk, CommonPrims ep) { MeshLib.AnimLib animLib = new MeshLib.AnimLib(); AnimForm af = new AnimForm(gd, matLib, animLib); StripElements se = new StripElements(); SkeletonEditor skel = new SkeletonEditor(); SharedForms.MaterialForm matForm = new SharedForms.MaterialForm(matLib, sk); SharedForms.CelTweakForm celForm = new SharedForms.CelTweakForm(gd, matLib); SharedForms.Output outForm = new SharedForms.Output(); //save positions matForm.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "MaterialFormPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); matForm.DataBindings.Add(new System.Windows.Forms.Binding("Size", Settings.Default, "MaterialFormSize", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); af.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "AnimFormPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); skel.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "SkeletonEditorFormPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); skel.DataBindings.Add(new System.Windows.Forms.Binding("Size", Settings.Default, "SkeletonEditorFormSize", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); celForm.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "CelTweakFormPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); outForm.DataBindings.Add(new System.Windows.Forms.Binding("Location", Settings.Default, "OutputFormPos", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); outForm.DataBindings.Add(new System.Windows.Forms.Binding("Size", Settings.Default, "OutputFormSize", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); SeamEditor seam = null; MakeSeamForm(ref seam); af.eMeshChanged += (sender, args) => matForm.SetMesh(sender); af.ePrint += (sender, args) => outForm.Print(sender as string); matForm.eNukedMeshPart += (sender, args) => af.NukeMeshPart(sender as List <int>); matForm.eStripElements += (sender, args) => { if (se.Visible) { return; } se.Populate(args as ArchEventArgs); }; matForm.eGenTangents += (sender, args) => { ArchEventArgs aea = args as ArchEventArgs; if (aea != null) { aea.mArch.GenTangents(gd, aea.mIndexes, matForm.GetTexCoordSet()); } }; matForm.eFoundSeams += (sender, args) => { if (seam.IsDisposed) { MakeSeamForm(ref seam); } seam.Initialize(gd); seam.AddSeams(sender as List <EditorMesh.WeightSeam>); seam.SizeColumns(); seam.Visible = true; }; se.eDeleteElement += (sender, args) => { List <int> elements = sender as List <int>; af.NukeVertexElement(se.GetIndexes(), elements); se.Populate(null); se.Visible = false; matForm.RefreshMeshPartList(); }; se.eEscape += (sender, args) => { se.Populate(null); se.Visible = false; }; af.eSkeletonChanged += (sender, args) => skel.Initialize(sender as MeshLib.Skeleton); af.eBoundsChanged += (sender, args) => ep.ReBuildBoundsDrawData(gd, sender); skel.eSelectUnUsedBones += (sender, args) => af.GetBoneNamesInUseByDraw(sender as List <string>); skel.eBonesChanged += (sender, args) => af.BonesChanged(); af.Visible = true; matForm.Visible = true; skel.Visible = true; celForm.Visible = true; outForm.Visible = true; return(af); }
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); }