protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Translation); if (node == null) { return(null); } ISnapSettings snapSettings = (ISnapSettings)DesignView; Path <DomNode> path = new Path <DomNode>(node.Cast <DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); Matrix4F toworld = new Matrix4F(); if (snapSettings.ManipulateLocalAxis) { toworld.Set(localToWorld); toworld.Normalize(toworld); } else { toworld.Translation = localToWorld.Translation; } Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); // Offset by pivot Matrix4F P = new Matrix4F(); P.Translation = offset; toworld.Mul(toworld, P); return(toworld); }
/// <summary> /// Calculates the transformation matrix corresponding to the given transform components</summary> /// <param name="translation">Translation</param> /// <param name="rotation">Rotation</param> /// <param name="scale">Scale</param> /// <param name="scalePivot">Translation to origin of scaling</param> /// <param name="scalePivotTranslate">Translation after scaling</param> /// <param name="rotatePivot">Translation to origin of rotation</param> /// <param name="rotatePivotTranslate">Translation after rotation</param> /// <returns>Transformation matrix corresponding to the given transform components</returns> public static Matrix4F CalcTransform( Vec3F translation, Vec3F rotation, Vec3F scale, Vec3F scalePivot, Vec3F scalePivotTranslate, Vec3F rotatePivot, Vec3F rotatePivotTranslate) { Matrix4F M = new Matrix4F(); Matrix4F temp = new Matrix4F(); M.Set(-scalePivot); temp.Scale(scale); M.Mul(M, temp); temp.Set(scalePivot + scalePivotTranslate - rotatePivot); M.Mul(M, temp); if (rotation.X != 0) { temp.RotX(rotation.X); M.Mul(M, temp); } if (rotation.Y != 0) { temp.RotY(rotation.Y); M.Mul(M, temp); } if (rotation.Z != 0) { temp.RotZ(rotation.Z); M.Mul(M, temp); } temp.Set(rotatePivot + rotatePivotTranslate + translation); M.Mul(M, temp); return(M); }
protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Pivot); if (node == null) { return(null); } Path <DomNode> path = new Path <DomNode>(node.Cast <DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); // Offset by pivot Matrix4F Pv = new Matrix4F(); Pv.Set(node.Pivot); localToWorld.Mul(Pv, localToWorld); localToWorld.OrthoNormalize(localToWorld); return(new Matrix4F(localToWorld.Translation)); }
protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Translation); if (node == null) { return(null); } ISnapSettings snapSettings = (ISnapSettings)DesignView; Path <DomNode> path = new Path <DomNode>(node.Cast <DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); Matrix4F toworld = new Matrix4F(); if (snapSettings.ManipulateLocalAxis) { toworld.Set(localToWorld); toworld.Normalize(toworld); } else { toworld.Translation = localToWorld.Translation; } // DavidJ -- note -- this "pivot" behaviour was inherited from another manipulator // but appears to be broken! Check coordinate space of value returned from CalcSnapFromOffset // Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); // // // Offset by pivot // Matrix4F P = new Matrix4F(); // P.Translation = offset; // toworld.Mul(toworld,P); return(toworld); }
/// <summary> /// Pushes a matrix onto the matrix stack</summary> /// <param name="matrix">The matrix</param> /// <param name="multiply">If true, multiply matrix by top matrix</param> public void PushMatrix(Matrix4F matrix, bool multiply) { if (m_matrixStackFreeze) { throw new InvalidOperationException( "the IRenderObject does not implement ISetsLocalTransform"); } int count = m_matrixStack.Count; Matrix4F topMatrix = (count > 0) ? m_matrixStack[count - 1] : Matrix4F.Identity; Matrix4F newMatrix = new Matrix4F(); if (multiply) { newMatrix.Mul(matrix, topMatrix); } else { newMatrix.Set(matrix); } m_matrixStack.Add(newMatrix); }
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); } }
private void RenderProperties(IEnumerable<object> objects, bool renderCaption, bool renderBound, bool renderPivot) { if (renderCaption || renderBound) { Util3D.RenderFlag = BasicRendererFlags.WireFrame; Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix; foreach (object obj in objects) { IBoundable bnode = obj.As<IBoundable>(); if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is<IGameObjectFolder>()) continue; INameable nnode = obj.As<INameable>(); ITransformable trans = obj.As<ITransformable>(); if (renderBound) { Util3D.DrawAABB(bnode.BoundingBox); } if (renderCaption && nnode != null) { Vec3F topCenter = bnode.BoundingBox.Center; topCenter.Y = bnode.BoundingBox.Max.Y; Point pt = Project(vp, topCenter); GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White); } } } if (renderPivot) { Util3D.RenderFlag = BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest; // create few temp matrics to Matrix4F toWorld = new Matrix4F(); Matrix4F PV = new Matrix4F(); Matrix4F sc = new Matrix4F(); Matrix4F bl = new Matrix4F(); Matrix4F recXform = new Matrix4F(); foreach (object obj in objects) { ITransformable trans = obj.As<ITransformable>(); IBoundable bnode = obj.As<IBoundable>(); if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is<IGameObjectFolder>()) continue; Path<DomNode> path = new Path<DomNode>(trans.Cast<DomNode>().GetPath()); toWorld.Set(Vec3F.ZeroVector); TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1); // Offset by pivot PV.Set(trans.Pivot); toWorld.Mul(PV, toWorld); Vec3F pos = toWorld.Translation; const float pivotDiameter = 16; // in pixels float s = Util.CalcAxisScale(Camera, pos, pivotDiameter, Height); sc.Scale(s); Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt); recXform = sc * bl; Util3D.DrawPivot(recXform, Color.Yellow); } } }
/// <summary> /// Calculates the transformation matrix corresponding to the given transform components /// </summary> /// <param name="translation">Translation</param> /// <param name="rotation">Rotation</param> /// <param name="scale">Scale</param> /// <param name="scalePivot">Translation to origin of scaling</param> /// <param name="scalePivotTranslate">Translation after scaling</param> /// <param name="rotatePivot">Translation to origin of rotation</param> /// <param name="rotatePivotTranslate">Translation after rotation</param> /// <returns>transformation matrix corresponding to the given transform components</returns> public static Matrix4F CalcTransform( Vec3F translation, Vec3F rotation, Vec3F scale, Vec3F pivot) { Matrix4F M = new Matrix4F(); Matrix4F temp = new Matrix4F(); M.Set(-pivot); temp.Scale(scale); M.Mul(M, temp); if (rotation.X != 0) { temp.RotX(rotation.X); M.Mul(M, temp); } if (rotation.Y != 0) { temp.RotY(rotation.Y); M.Mul(M, temp); } if (rotation.Z != 0) { temp.RotZ(rotation.Z); M.Mul(M, temp); } temp.Set(pivot + translation); M.Mul(M, temp); return M; }
/// <summary> /// Performs initialization when the adapter's node is set. /// This method is called each time the adapter is connected to its underlying node. /// Typically overridden by creators of DOM adapters.</summary> protected override void OnNodeSet() { base.OnNodeSet(); // get trans, scale, and rot. foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.scaleChild)) { m_scale = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute); break; } foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.translateChild)) { m_translation = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute); break; } const float PiOver180 = (float)(Math.PI / 180.0f); foreach (DomNode node in DomNode.GetChildList(Schema.node.rotateChild)) { double[] arr = (double[])node.GetAttribute(Schema.rotate.Attribute); float angle = (float)arr[3] * PiOver180; string sid = node.GetAttribute(Schema.rotate.sidAttribute) as string; if (string.IsNullOrEmpty(sid)) continue; if (sid == "rotateX") m_rotation.X = angle; else if (sid == "rotateY") m_rotation.Y = angle; else if (sid == "rotateZ") m_rotation.Z = angle; } Matrix4F M = new Matrix4F(); Matrix4F temp = new Matrix4F(); temp.Scale(Scale); M.Mul(M, temp); if (m_rotation.X != 0) { temp.RotX(m_rotation.X); M.Mul(M, temp); } if (m_rotation.Y != 0) { temp.RotY(m_rotation.Y); M.Mul(M, temp); } if (m_rotation.Z != 0) { temp.RotZ(m_rotation.Z); M.Mul(M, temp); } temp.Set(Translation); M.Mul(M, temp); Transform = M; m_boundingBox = new Cached<Box>(CalculateBoundingBox); Visible = true; }
protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Pivot); if (node == null) return null; Path<DomNode> path = new Path<DomNode>(node.Cast<DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); // Offset by pivot Matrix4F Pv = new Matrix4F(); Pv.Set(node.Pivot); localToWorld.Mul(Pv, localToWorld); localToWorld.OrthoNormalize(localToWorld); return new Matrix4F(localToWorld.Translation); }
private void RenderProperties(IEnumerable <object> objects, bool renderCaption, bool renderBound, bool renderPivot) { bool renderAny = renderCaption || renderBound || renderPivot; if (renderAny == false) { return; } Util3D.RenderFlag = BasicRendererFlags.WireFrame; Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix; foreach (object obj in objects) { IBoundable bnode = obj.As <IBoundable>(); if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>()) { continue; } INameable nnode = obj.As <INameable>(); ITransformable trans = obj.As <ITransformable>(); if (renderBound) { Util3D.DrawAABB(bnode.BoundingBox); } if (renderCaption && nnode != null) { Vec3F topCenter = bnode.BoundingBox.Center; topCenter.Y = bnode.BoundingBox.Max.Y; Point pt = Project(vp, topCenter); GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White); } } if (renderPivot) { Util3D.RenderFlag = BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest; // create few temp matrics to Matrix4F toWorld = new Matrix4F(); Matrix4F PV = new Matrix4F(); Matrix4F sc = new Matrix4F(); Matrix4F bl = new Matrix4F(); Matrix4F recXform = new Matrix4F(); foreach (object obj in objects) { ITransformable trans = obj.As <ITransformable>(); IBoundable bnode = obj.As <IBoundable>(); if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>()) { continue; } Path <DomNode> path = new Path <DomNode>(trans.Cast <DomNode>().GetPath()); toWorld.Set(Vec3F.ZeroVector); TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1); // Offset by pivot PV.Set(trans.Pivot); toWorld.Mul(PV, toWorld); Vec3F pos = toWorld.Translation; float s; Util.CalcAxisLengths(Camera, pos, out s); s /= 12.0f; sc.Scale(s); Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt); Matrix4F.Multiply(sc, bl, recXform); Util3D.DrawPivot(recXform, Color.Yellow); } } }
protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Translation); if (node == null ) return null; ISnapSettings snapSettings = (ISnapSettings)DesignView; Path<DomNode> path = new Path<DomNode>(node.Cast<DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); Matrix4F toworld = new Matrix4F(); if (snapSettings.ManipulateLocalAxis) { toworld.Set(localToWorld); toworld.Normalize(toworld); } else { toworld.Translation = localToWorld.Translation; } Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); // Offset by pivot Matrix4F P = new Matrix4F(); P.Translation = offset; toworld.Mul(toworld,P); return toworld; }
/// <summary> /// Pushes a matrix onto the matrix stack</summary> /// <param name="matrix">The matrix</param> /// <param name="multiply">If true, multiply matrix by top matrix</param> public void PushMatrix(Matrix4F matrix, bool multiply) { if (m_matrixStackFreeze) throw new InvalidOperationException( "the IRenderObject does not implement ISetsLocalTransform"); int count = m_matrixStack.Count; Matrix4F topMatrix = (count > 0) ? m_matrixStack[count - 1] : Matrix4F.Identity; Matrix4F newMatrix = new Matrix4F(); if (multiply) newMatrix.Mul(matrix, topMatrix); else newMatrix.Set(matrix); m_matrixStack.Add(newMatrix); }
/// <summary> /// Performs initialization when the adapter's node is set. /// This method is called each time the adapter is connected to its underlying node. /// Typically overridden by creators of DOM adapters.</summary> protected override void OnNodeSet() { base.OnNodeSet(); // get trans, scale, and rot. foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.scaleChild)) { m_scale = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute); break; } foreach (DomNode domNode in this.DomNode.GetChildList(Schema.node.translateChild)) { m_translation = Tools.GetVector3(domNode, Schema.TargetableFloat3.Attribute); break; } const float PiOver180 = (float)(Math.PI / 180.0f); foreach (DomNode node in DomNode.GetChildList(Schema.node.rotateChild)) { double[] arr = (double[])node.GetAttribute(Schema.rotate.Attribute); float angle = (float)arr[3] * PiOver180; string sid = node.GetAttribute(Schema.rotate.sidAttribute) as string; if (string.IsNullOrEmpty(sid)) { continue; } if (sid == "rotateX") { m_rotation.X = angle; } else if (sid == "rotateY") { m_rotation.Y = angle; } else if (sid == "rotateZ") { m_rotation.Z = angle; } } Matrix4F M = new Matrix4F(); Matrix4F temp = new Matrix4F(); temp.Scale(Scale); M.Mul(M, temp); if (m_rotation.X != 0) { temp.RotX(m_rotation.X); M.Mul(M, temp); } if (m_rotation.Y != 0) { temp.RotY(m_rotation.Y); M.Mul(M, temp); } if (m_rotation.Z != 0) { temp.RotZ(m_rotation.Z); M.Mul(M, temp); } temp.Set(Translation); M.Mul(M, temp); Transform = M; m_boundingBox = new Cached <Box>(CalculateBoundingBox); Visible = true; }
protected override Matrix4F GetManipulatorMatrix() { ITransformable node = GetManipulatorNode(TransformationTypes.Translation); if (node == null) return null; ISnapSettings snapSettings = (ISnapSettings)DesignView; Path<DomNode> path = new Path<DomNode>(node.Cast<DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); Matrix4F toworld = new Matrix4F(); if (snapSettings.ManipulateLocalAxis) { toworld.Set(localToWorld); toworld.Normalize(toworld); } else { toworld.Translation = localToWorld.Translation; } // DavidJ -- note -- this "pivot" behaviour was inherited from another manipulator // but appears to be broken! Check coordinate space of value returned from CalcSnapFromOffset // Vec3F offset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); // // // Offset by pivot // Matrix4F P = new Matrix4F(); // P.Translation = offset; // toworld.Mul(toworld,P); return toworld; }
private void RenderProperties(GUILayer.SimpleRenderingContext context, IEnumerable <object> objects, bool renderCaption, bool renderBound, bool renderPivot) { if (renderCaption || renderBound) { Util3D.SetRenderFlag(context, BasicRendererFlags.WireFrame); Matrix4F vp = Camera.ViewMatrix * Camera.ProjectionMatrix; foreach (object obj in objects) { IBoundable bnode = obj.As <IBoundable>(); if (bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>()) { continue; } INameable nnode = obj.As <INameable>(); ITransformable trans = obj.As <ITransformable>(); if (renderBound) { Util3D.DrawAABB(context, bnode.BoundingBox); } if (renderCaption && nnode != null) { Vec3F topCenter = bnode.BoundingBox.Center; topCenter.Y = bnode.BoundingBox.Max.Y; Point pt = Project(vp, topCenter); GameEngine.DrawText2D(nnode.Name, Util3D.CaptionFont, pt.X, pt.Y, Color.White); } } } if (renderPivot) { Util3D.SetRenderFlag(context, BasicRendererFlags.WireFrame | BasicRendererFlags.DisableDepthTest); // create few temp matrics to Matrix4F toWorld = new Matrix4F(); Matrix4F PV = new Matrix4F(); Matrix4F sc = new Matrix4F(); Matrix4F bl = new Matrix4F(); Matrix4F recXform = new Matrix4F(); foreach (object obj in objects) { ITransformable trans = obj.As <ITransformable>(); IBoundable bnode = obj.As <IBoundable>(); if (trans == null || bnode == null || bnode.BoundingBox.IsEmpty || obj.Is <IGameObjectFolder>()) { continue; } Path <DomNode> path = new Path <DomNode>(trans.Cast <DomNode>().GetPath()); toWorld.Set(Vec3F.ZeroVector); TransformUtils.CalcPathTransform(toWorld, path, path.Count - 1); // Offset by pivot PV.Set(trans.Pivot); toWorld.Mul(PV, toWorld); Vec3F pos = toWorld.Translation; const float pivotDiameter = 16; // in pixels float s = Util.CalcAxisScale(Camera, pos, pivotDiameter, Height); sc.Scale(s); Util.CreateBillboard(bl, pos, Camera.WorldEye, Camera.Up, Camera.LookAt); recXform = sc * bl; Util3D.DrawPivot(context, recXform, Color.Yellow); } } }
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.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); } }