public void LoadJNT1FromStream(EndianBinaryReader reader, long tagStart) { ushort numJoints = reader.ReadUInt16(); Trace.Assert(reader.ReadUInt16() == 0xFFFF); // Padding int jointDataOffset = reader.ReadInt32(); int jointRemapDataOffset = reader.ReadInt32(); int stringTableOffset = reader.ReadInt32(); // Joint Names reader.BaseStream.Position = tagStart + stringTableOffset; StringTable nameTable = StringTable.FromStream(reader); // Joint Index Remap reader.BaseStream.Position = tagStart + jointRemapDataOffset; JointRemapTable = new List <short>(); for (int i = 0; i < numJoints; i++) { JointRemapTable.Add(reader.ReadInt16()); } // Joint Data reader.BaseStream.Position = tagStart + jointDataOffset; BindJoints = new List <SkeletonJoint>(numJoints); AnimatedJoints = new List <SkeletonJoint>(numJoints); for (int j = 0; j < numJoints; j++) { SkeletonJoint joint = new SkeletonJoint(); BindJoints.Add(joint); joint.Name = nameTable[j]; joint.Unknown1 = reader.ReadUInt16(); joint.DoNotInheritParentScale = reader.ReadByte() == 1; Trace.Assert(reader.ReadByte() == 0xFF); // Padding joint.Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 eulerRot = new Vector3(); for (int e = 0; e < 3; e++) { eulerRot[e] = WMath.RotationShortToFloat(reader.ReadInt16()); } // ZYX order joint.Rotation = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), WMath.DegreesToRadians(eulerRot.Z)) * Quaternion.FromAxisAngle(new Vector3(0, 1, 0), WMath.DegreesToRadians(eulerRot.Y)) * Quaternion.FromAxisAngle(new Vector3(1, 0, 0), WMath.DegreesToRadians(eulerRot.X)); Trace.Assert(reader.ReadUInt16() == 0xFFFF); // Padding joint.Translation = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); joint.BoundingSphereDiameter = reader.ReadSingle(); joint.BoundingBox = new FAABox(new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); // Copy our bind pose skeleton over to our AnimatedJoints array so they have their names/bounding boxes/etc set. var animatedJoint = new SkeletonJoint(); joint.CopyTo(ref animatedJoint); AnimatedJoints.Add(animatedJoint); } }
public void ApplyAnimationToPose(List <SkeletonJoint> pose) { if (pose.Count != m_animationData.Count) { Console.WriteLine("Mis-matched number of joints in pose and number of joints in animation!"); } int numJoints = Math.Min(pose.Count, m_animationData.Count); float ftime = (m_timeSinceStartedPlaying * kAnimFramerate) % AnimLengthInFrames; for (int i = 0; i < numJoints; i++) { pose[i].Scale = new Vector3(GetAnimValue(m_animationData[i].ScalesX, ftime), GetAnimValue(m_animationData[i].ScalesY, ftime), GetAnimValue(m_animationData[i].ScalesZ, ftime)); Vector3 rot = new Vector3(GetAnimValue(m_animationData[i].RotationsX, ftime), GetAnimValue(m_animationData[i].RotationsY, ftime), GetAnimValue(m_animationData[i].RotationsZ, ftime)); // ZYX order pose[i].Rotation = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), WMath.DegreesToRadians(rot.Z)) * Quaternion.FromAxisAngle(new Vector3(0, 1, 0), WMath.DegreesToRadians(rot.Y)) * Quaternion.FromAxisAngle(new Vector3(1, 0, 0), WMath.DegreesToRadians(rot.X)); Vector3 translation = new Vector3(GetAnimValue(m_animationData[i].TranslationsX, ftime), GetAnimValue(m_animationData[i].TranslationsY, ftime), GetAnimValue(m_animationData[i].TranslationsZ, ftime)); pose[i].Translation = translation; } }
public CollisionGroupNode(EndianBinaryReader reader) { Children = new ObservableCollection <CollisionGroupNode>(); Triangles = new List <CollisionTriangle>(); int name_offset = reader.ReadInt32(); long cur_offset = reader.BaseStream.Position; reader.BaseStream.Seek(name_offset, System.IO.SeekOrigin.Begin); Name = Encoding.ASCII.GetString(reader.ReadBytesUntil(0)); reader.BaseStream.Seek(cur_offset, System.IO.SeekOrigin.Begin); m_Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 eulerRot = new Vector3(); for (int e = 0; e < 3; e++) { eulerRot[e] = WMath.RotationShortToFloat(reader.ReadInt16()); } // ZYX order m_Rotation = OpenTK.Quaternion.FromAxisAngle(new Vector3(0, 0, 1), WMath.DegreesToRadians(eulerRot.Z)) * OpenTK.Quaternion.FromAxisAngle(new Vector3(0, 1, 0), WMath.DegreesToRadians(eulerRot.Y)) * OpenTK.Quaternion.FromAxisAngle(new Vector3(1, 0, 0), WMath.DegreesToRadians(eulerRot.X)); m_Unknown1 = reader.ReadUInt16(); m_Translation = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); m_ParentIndex = reader.ReadInt16(); m_NextSiblingIndex = reader.ReadInt16(); m_FirstChildIndex = reader.ReadInt16(); m_RoomNum = reader.ReadInt16(); FirstVertexIndex = reader.ReadInt16(); reader.SkipInt16(); // Octree index, we don't need it for loading from dzb m_Bitfield = reader.ReadInt32(); }
private static Quaternion FromEulerAngles(Vector3 e) { e.X = WMath.DegreesToRadians(e.X); e.Y = WMath.DegreesToRadians(e.Y); e.Z = WMath.DegreesToRadians(e.Z); double c1 = Math.Cos(e.Y / 2f); double s1 = Math.Sin(e.Y / 2f); double c2 = Math.Cos(e.X / 2f); double s2 = Math.Sin(e.X / 2f); double c3 = Math.Cos(e.Z / 2f); double s3 = Math.Sin(e.Z / 2f); double c1c2 = c1 * c2; double s1s2 = s1 * s2; float w = (float)(c1c2 * c3 - s1s2 * s3); float x = (float)(c1c2 * s3 + s1s2 * c3); float y = (float)(s1 * c2 * c3 + c1 * s2 * s3); float z = (float)(c1 * s2 * c3 - s1 * c2 * s3); return new Quaternion(x, y, z, w); }
private void RenderFrame() { m_frameBuffer.Bind(); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); GL.Viewport(0, 0, m_frameBuffer.Width, m_frameBuffer.Height); float deltaTime = m_dtStopwatch.ElapsedMilliseconds / 1000f; m_dtStopwatch.Restart(); m_renderCamera.Tick(deltaTime); m_lineBatcher.Tick(deltaTime); m_skeletonLineBatcher.Tick(deltaTime); deltaTime = WMath.Clamp(deltaTime, 0, 0.25f); // quarter second max because debugging m_timeSinceStartup += deltaTime; if (m_modelRenderOptions.AnimateLight) { // Rotate our light float angleInRad = m_timeSinceStartup % WMath.DegreesToRadians(360f); m_mainLight.Position = new Vector4(CalculateLightPosition(angleInRad), 0); } if (m_modelRenderOptions.ShowGrid) { DrawFixedGrid(); } if (m_modelRenderOptions.DepthPrePass) { foreach (var j3d in m_loadedModels) { // Render a depth-only pre pass. We need to tell it to render translucent and opaque objects so that // they both write in to the depth buffer (it's a specific pre-pass so they should) j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, true, true, true); } } foreach (var j3d in m_loadedModels) { j3d.Tick(deltaTime); } foreach (var j3d in m_loadedModels) { j3d.SetHardwareLight(0, m_mainLight); j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, true, false); } foreach (var j3d in m_loadedModels) { // Do a second render pass after all objects to render translucent ones. j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, false, true); } if (m_modelRenderOptions.ShowPivot) { m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(50, 0, 0), WLinearColor.Red, 0, 0); m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(0, 50, 0), WLinearColor.Green, 0, 0); m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(0, 0, 50), WLinearColor.Blue, 0, 0); } if (m_modelRenderOptions.ShowBoundingBox) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForShapes(true, false, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoundingSphere) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForShapes(false, true, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoneBoundingBox) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForJoints(true, false, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoneBoundingSphere) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForJoints(false, true, m_lineBatcher); } } if (m_modelRenderOptions.ShowBones) { foreach (var j3d in m_loadedModels) { j3d.DrawBones(m_skeletonLineBatcher); } } // Debug Rendering if (WInput.GetKey(Key.I)) { GL.Disable(EnableCap.CullFace); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.DstAlpha, BlendingFactorDest.Zero); m_alphaVisualizationShader.Bind(); m_screenQuad.Draw(); } // Blit the framebuffer to the backbuffer so it shows up on screen. m_lineBatcher.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix); m_skeletonLineBatcher.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, true); m_frameBuffer.BlitToBackbuffer(m_viewportWidth, m_viewportHeight); }
public MainWindowViewModel() { // Override the Current Directory with one we calculate ourself. This solves the problem of assigning the application as the // default application for a filetype and it having its CurrentDirectory be System32. Environment.CurrentDirectory = ApplicationExtensions.GetBasePath(); m_highresScreenshot = new HighresScreenshotViewModel(); m_modelRenderOptions = new ModelRenderOptionsViewModel(); m_renderCamera = new WCamera(); m_loadedModels = new List <J3D>(); m_sceneGraphs = new List <SceneGraphViewModel>(); m_renderCamera.Transform.Position = new Vector3(500, 75, 500); m_renderCamera.Transform.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, WMath.DegreesToRadians(45f)); m_dtStopwatch = new System.Diagnostics.Stopwatch(); Application.Current.MainWindow.Closing += OnMainWindowClosing; Random rnd = new Random((int)DateTime.Now.ToBinary()); m_glControlClearColor = ColorUtils.HSVtoRGB(new Vector3(rnd.Next(255) / 255f, 0.7f, 0.85f)); }