Ejemplo n.º 1
0
 /// <summary>
 /// Decomposes the given matrix to translation, scale, 
 /// and rotation and set them to given Transformable node.        
 /// </summary>        
 public static void SetTransform(ITransformable xform, Matrix4F mtrx)
 {
     xform.Translation = mtrx.Translation;
     xform.Scale = mtrx.GetScale();
     Vec3F rot = new Vec3F();
     mtrx.GetEulerAngles(out rot.X, out rot.Y, out rot.Z);
     xform.Rotation = rot;
     xform.UpdateTransform();
 }
Ejemplo n.º 2
0
        private void SetTransform(ITransformable xform, Matrix4F mtrx)
        {
            xform.Translation = mtrx.Translation;
            xform.Scale       = mtrx.GetScale();
            Vec3F rot = new Vec3F();

            mtrx.GetEulerAngles(out rot.X, out rot.Y, out rot.Z);
            xform.Rotation = rot;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Adjusts child transform, making it the concatenation with its parent's transform.
        /// Is recursive, looking for parents that also implement IRenderableNode.</summary>
        /// <param name="parent">Parent node</param>
        /// <param name="child">Child node</param>
        public static void RemoveChild(ITransformable parent, ITransformable child)
        {
            Path <DomNode> path         = new Path <DomNode>(parent.Cast <DomNode>().GetPath());
            Matrix4F       parentMatrix = TransformUtils.CalcPathTransform(path, path.Count - 1);

            Matrix4F childMatrix    = child.Transform;
            Matrix4F newChildMatrix = Matrix4F.Multiply(childMatrix, parentMatrix);

            Vec3F newTranslation = child.Translation;

            parentMatrix.Transform(ref newTranslation);

            Vec3F newRotation = new Vec3F();

            newChildMatrix.GetEulerAngles(out newRotation.X, out newRotation.Y, out newRotation.Z);
            child.Rotation = newRotation;

            Vec3F newScale = newChildMatrix.GetScale();

            child.Scale = newScale;

            // We can compose together all of the separate transformations now.
            Matrix4F newTransform = CalcTransform(
                newTranslation,
                newRotation,
                newScale,
                child.ScalePivot,
                child.ScalePivotTranslation,
                child.RotatePivot,
                child.RotatePivotTranslation);

            // However, the composed matrix may not equal newChildMatrix due to rotating
            //  or scaling around a pivot. In the general case, it may be impossible to
            //  decompose newChildMatrix into all of these separate components. For example,
            //  a sheer transformation cannot be reproduced by a single rotation and scale.
            //  But for common cases, only the translation is out-of-sync now, so apply a fix.
            Vec3F    desiredTranslation = newChildMatrix.Translation;
            Vec3F    currentTranslation = newTransform.Translation;
            Vec3F    fixupTranslation   = desiredTranslation - currentTranslation;
            Matrix4F fixupTransform     = new Matrix4F(fixupTranslation);

            newTransform.Mul(newTransform, fixupTransform);

            // Save the fix and the final transform.
            child.Translation = newTranslation + fixupTranslation;
            child.Transform   = newTransform;
        }
Ejemplo n.º 4
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F proj = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F hitRay = HitRayV;
            Ray3F dragRay = vc.GetRay(scrPt, proj);
            
            Vec3F xAxis = axisMtrx.XAxis;
            Vec3F yAxis = axisMtrx.YAxis;
            Vec3F zAxis = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;
            
            Vec3F rotAxis = new Vec3F();            
            float theta = 0;

            float snapAngle = ((ISnapSettings)DesignView).SnapAngle;
            switch (m_hitRegion)
            {                
                case HitRegion.XAxis:
                    {
                        Plane3F xplane = new Plane3F(xAxis, origin);
                        theta = CalcAngle(origin, xplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.XAxis;                        
                    }
                    break;
                case HitRegion.YAxis:
                    {
                        Plane3F yplane = new Plane3F(yAxis, origin);
                        theta = CalcAngle(origin, yplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.YAxis;                        
                    }
                    break;
                case HitRegion.ZAxis:
                    {
                        Plane3F zplane = new Plane3F(zAxis, origin);
                        theta = CalcAngle(origin, zplane, hitRay, dragRay, snapAngle);
                        rotAxis = HitMatrix.ZAxis;
                    }
                    break;
                case HitRegion.LookAxis:
                    {                        
                        // for billboard objects the look vector is object's negative position in viewspace.
                        Vec3F lookAxis = Vec3F.Normalize(-origin);
                        Plane3F plane = new Plane3F(lookAxis, origin);
                        theta = CalcAngle(origin, plane, hitRay, dragRay, snapAngle);                        
                        rotAxis = m_lookAxisHitMtrx.ZAxis;
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf = new AngleAxisF(-theta, rotAxis);
            Matrix4F deltaMtrx = new Matrix4F(axf);                                   
            Matrix4F rotMtrx = new Matrix4F();

            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];                              
                rotMtrx.Mul(m_rotations[i], deltaMtrx);                
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);                                
                node.Rotation = new Vec3F(ax, ay, az);      
            }
        }
Ejemplo n.º 5
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
                return;
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F mtrx = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F hitRay = HitRayV;
            Ray3F dragRay = vc.GetRay(scrPt, mtrx);
            
            Vec3F xAxis = axisMtrx.XAxis;
            Vec3F yAxis = axisMtrx.YAxis;
            Vec3F zAxis = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;
            
            Vec3F rotAxis = new Vec3F();
            float theta = 0;
            
            switch (m_hitRegion)
            {                
                case HitRegion.XAxis:
                    {
                        Plane3F xplane = new Plane3F(xAxis, origin);
                        theta = CalcAngle(origin, xplane, hitRay, dragRay);
                        rotAxis = HitMatrix.XAxis;                     
                    }
                    break;
                case HitRegion.YAxis:
                    {
                        Plane3F yplane = new Plane3F(yAxis, origin);
                        theta = CalcAngle(origin, yplane, hitRay, dragRay);
                        rotAxis = HitMatrix.YAxis;

                    }
                    break;
                case HitRegion.ZAxis:
                    {
                        Plane3F zplane = new Plane3F(zAxis, origin);
                        theta = CalcAngle(origin, zplane, hitRay, dragRay);
                        rotAxis = HitMatrix.ZAxis;
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf = new AngleAxisF(-theta, rotAxis);
            Matrix4F deltaMtrx = new Matrix4F(axf);                                   
            Matrix4F rotMtrx = new Matrix4F();            
            for (int i = 0; i < NodeList.Count; i++)
            {                                
                ITransformable node = NodeList[i];                
                rotMtrx.Set(m_rotations[i]);
                rotMtrx.Mul(rotMtrx, deltaMtrx);                
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);                
                node.Rotation = new Vec3F(ax,ay,az);
            }

        }
Ejemplo n.º 6
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || NodeList.Count == 0)
            {
                return;
            }
            Camera cam = vc.Camera;

            Matrix4F view = cam.ViewMatrix;
            Matrix4F mtrx = cam.ProjectionMatrix;

            Matrix4F axisMtrx = HitMatrix * view;
            Ray3F    hitRay   = HitRayV;
            Ray3F    dragRay  = vc.GetRay(scrPt, mtrx);

            Vec3F xAxis  = axisMtrx.XAxis;
            Vec3F yAxis  = axisMtrx.YAxis;
            Vec3F zAxis  = axisMtrx.ZAxis;
            Vec3F origin = axisMtrx.Translation;

            Vec3F rotAxis = new Vec3F();
            float theta   = 0;

            float snapAngle = ((ISnapSettings)DesignView).SnapAngle;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            {
                Plane3F xplane = new Plane3F(xAxis, origin);
                theta   = CalcAngle(origin, xplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.XAxis;
            }
            break;

            case HitRegion.YAxis:
            {
                Plane3F yplane = new Plane3F(yAxis, origin);
                theta   = CalcAngle(origin, yplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.YAxis;
            }
            break;

            case HitRegion.ZAxis:
            {
                Plane3F zplane = new Plane3F(zAxis, origin);
                theta   = CalcAngle(origin, zplane, hitRay, dragRay, snapAngle);
                rotAxis = HitMatrix.ZAxis;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            AngleAxisF axf       = new AngleAxisF(-theta, rotAxis);
            Matrix4F   deltaMtrx = new Matrix4F(axf);
            Matrix4F   rotMtrx   = new Matrix4F();

            for (int i = 0; i < NodeList.Count; i++)
            {
                ITransformable node = NodeList[i];
                rotMtrx.Mul(m_rotations[i], deltaMtrx);
                float ax, ay, az;
                rotMtrx.GetEulerAngles(out ax, out ay, out az);
                node.Rotation = new Vec3F(ax, ay, az);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Adjusts child transform, making it relative to new parent node's transform.
        /// Is recursive, looking for parents that also implement IRenderableNode.</summary>
        /// <param name="parent">Parent node</param>
        /// <param name="child">Child node</param>
        public static void AddChild(ITransformable parent, ITransformable child)
        {
            Path <DomNode> path          = new Path <DomNode>(parent.Cast <DomNode>().GetPath());
            Matrix4F       parentToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1);

            // We want 'child' to appear in the same place in the world after adding to 'parent'.
            // local-point * original-local-to-world = world-point
            // new-local-point * new-local-to-parent * parent-to-world = world-point
            // ==> new-local-to-parent * parent-to-world = original-local-to-world
            // (multiply both sides by inverse of parent-to-world; call it world-to-parent)
            // ==> new-local-to-parent = original-local-to-world * world-to-parent
            Matrix4F worldToParent = new Matrix4F();

            worldToParent.Invert(parentToWorld);
            Matrix4F originalLocalToWorld = child.Transform;
            Matrix4F newLocalToParent     = Matrix4F.Multiply(originalLocalToWorld, worldToParent);

            // The translation component of newLocalToParent consists of pivot translation
            //  as well as the child.Translation. So, start with the original child.Translation
            //  and transform it into our new space.
            Vec3F newTranslation = child.Translation;

            worldToParent.Transform(ref newTranslation);

            // There's only one way of getting rotation info, so get it straight from matrix.
            Vec3F newRotation = new Vec3F();

            newLocalToParent.GetEulerAngles(out newRotation.X, out newRotation.Y, out newRotation.Z);
            child.Rotation = newRotation;

            // Likewise with scale.
            Vec3F newScale = newLocalToParent.GetScale();

            child.Scale = newScale;

            // We can compose together all of the separate transformations now.
            Matrix4F newTransform = CalcTransform(
                newTranslation,
                newRotation,
                newScale,
                child.ScalePivot,
                child.ScalePivotTranslation,
                child.RotatePivot,
                child.RotatePivotTranslation);

            // However, the composed matrix may not equal newLocalToParent due to rotating
            //  or scaling around a pivot. In the general case, it may be impossible to
            //  decompose newLocalToParent into all of these separate components. For example,
            //  a sheer transformation cannot be reproduced by a single rotation and scale.
            //  But for common cases, only the translation is out-of-sync now, so apply a fix.
            Vec3F    desiredTranslation = newLocalToParent.Translation;
            Vec3F    currentTranslation = newTransform.Translation;
            Vec3F    fixupTranslation   = desiredTranslation - currentTranslation;
            Matrix4F fixupTransform     = new Matrix4F(fixupTranslation);

            newTransform.Mul(newTransform, fixupTransform);

            // Save the fix and the final transform. Storing the fix in RotatePivotTranslation
            //  is done elsewhere, as well.
            child.Translation = newTranslation + fixupTranslation;
            child.Transform   = newTransform;
        }