Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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));
        }