コード例 #1
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                // Try to do gizmo picking
                if (DrawGizmo)
                {
                    var result = _gizmo.DoPicking(GetRay(e.X, e.Y));
                    if (result != null)
                    {
                        _gizmo.ActivateGizmo(result);
                        Invalidate();
                        return;
                    }
                }

                // Try to do node picking
                WadMeshBoneNode foundNode = null;
                foreach (var node in Skeleton)
                {
                    float distance    = 0;
                    float minDistance = float.PositiveInfinity;
                    if (DoNodePicking(GetRay(e.X, e.Y), node, out distance))
                    {
                        if (distance < minDistance)
                        {
                            distance  = minDistance;
                            foundNode = node;
                        }
                    }
                }
                SelectedNode = foundNode;
            }

            Invalidate();

            _lastX = e.X;
            _lastY = e.Y;

            base.OnMouseDown(e);
        }
コード例 #2
0
        private bool DoNodePicking(Ray ray, WadMeshBoneNode node, out float nodeDistance)
        {
            nodeDistance = 0;

            // Transform view ray to object space space
            Matrix4x4 inverseObjectMatrix;

            if (!Matrix4x4.Invert(node.GlobalTransform, out inverseObjectMatrix))
            {
                return(false);
            }
            Vector3 transformedRayPos         = MathC.HomogenousTransform(ray.Position, inverseObjectMatrix);
            Vector3 transformedRayDestination = MathC.HomogenousTransform(ray.Position + ray.Direction, inverseObjectMatrix);
            Ray     transformedRay            = new Ray(transformedRayPos, transformedRayDestination - transformedRayPos);

            transformedRay.Direction = Vector3.Normalize(transformedRay.Direction);

            // Now do a ray - triangle intersection test
            bool  hit         = false;
            float minDistance = float.PositiveInfinity;
            var   mesh        = node.WadMesh;

            foreach (var poly in mesh.Polys)
            {
                if (poly.Shape == WadPolygonShape.Quad)
                {
                    Vector3 p1 = mesh.VerticesPositions[poly.Index0];
                    Vector3 p2 = mesh.VerticesPositions[poly.Index1];
                    Vector3 p3 = mesh.VerticesPositions[poly.Index2];
                    Vector3 p4 = mesh.VerticesPositions[poly.Index3];

                    float distance;
                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }

                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p3, p4, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }
                }
                else
                {
                    Vector3 p1 = mesh.VerticesPositions[poly.Index0];
                    Vector3 p2 = mesh.VerticesPositions[poly.Index1];
                    Vector3 p3 = mesh.VerticesPositions[poly.Index2];

                    float distance;
                    if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
                    {
                        minDistance = distance;
                        hit         = true;
                    }
                }
            }

            /*
             * _wadRenderer.Dispose();
             * foreach (var submesh in node.Bone.Children.Select(bone => bone.Mesh))
             * for (int k = 0; k < submesh.Value.Indices.Count; k += 3)
             * {
             *  var mesh = _wadRenderer.GetStatic(new WadStatic(new WadStaticId(0)) { Mesh = node.WadMesh });
             *
             *  Vector3 p1 = mesh.Vertices[submesh.Value.Indices[k]].Position;
             *  Vector3 p2 = mesh.Vertices[submesh.Value.Indices[k + 1]].Position;
             *  Vector3 p3 = mesh.Vertices[submesh.Value.Indices[k + 2]].Position;
             *
             *  float distance;
             *  if (Collision.RayIntersectsTriangle(transformedRay, p1, p2, p3, out distance) && distance < minDistance)
             *  {
             *      minDistance = distance;
             *      hit = true;
             *  }
             * }*/
            // TODO Avoid using the renderer for pickingData transforms need to be available in wad mesh without rendering.
            int TODO_DoNodePicking;

            if (hit)
            {
                nodeDistance = minDistance;
                return(true);
            }
            else
            {
                return(false);
            }
        }