public override void OnRender() { base.OnRender(); if (!Owner.IsAllowRotate()) { return; } ColorValue yellow = new ColorValue(1, 1, 0); ColorValue red = new ColorValue(1, 0, 0); ColorValue green = new ColorValue(0, 1, 0); ColorValue blue = new ColorValue(0, 0, 1); ColorValue gray = new ColorValue(.66f, .66f, .66f); ColorValue darkGray = new ColorValue(.33f, .33f, .33f); ColorValue shadowColor = new ColorValue(0, 0, 0, ProjectSettings.Get.TransformToolShadowIntensity); Axis axis = Axis.None; if (!Viewport.MouseRelativeMode) { if (!modify_Activated) { Vector2 dummy1; Radian dummy2; axis = GetAxisByMousePosition(out dummy1, out dummy2); } else { axis = selectedAxis; } } Vector3 position; if (!modify_Activated) { position = Owner.GetPosition(); } else { position = modifyPosition; } double lineThickness = GetLineWorldThickness(position); double radius = GetSize(); if (radius == 0) { return; } //DebugGeometry.SetSpecialDepthSettings( false, true ); const double step = MathEx.PI / 64; double innerRadius = radius * .75f; double cameraDistance = GetCameraDistance(position); Vector3 cameraRight = Vector3.Cross(CameraSettings.Direction, CameraSettings.Up); Vector3 oldPos = Vector3.Zero; Quaternion startRotation = GetStartObjectsRotation(); for (int nDrawStep = 0; nDrawStep < 5; nDrawStep++) { bool drawShadows = nDrawStep <= 3; if (drawShadows && ProjectSettings.Get.TransformToolShadowIntensity == 0) { continue; } var drawShadowsFactor = 0.0; if (drawShadows) { drawShadowsFactor = ((double)nDrawStep + 1.0) / 4.0; } if (drawShadows) { DebugGeometry.SetColor(shadowColor * new ColorValue(1, 1, 1, 0.25), false); //, true ); } //Fill inner circle if (axis == Axis.InnerCircle && !drawShadows) { if (!drawShadows) { DebugGeometry.SetColor(new ColorValue(1, 1, 0, .4f), false); //, true ); } //DebugGeometry.Color = new ColorValue( .2f, .2f, .2f, .33f ); List <Vector3> vertices = new List <Vector3>(); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position; pos += cameraRight * Math.Cos(angle) * innerRadius; pos += CameraSettings.Up * Math.Sin(angle) * innerRadius; if (angle != 0) { int verticesCount = vertices.Count; vertices.Add(position); vertices.Add(oldPos); vertices.Add(pos); } oldPos = pos; } DebugGeometry.AddTriangles(vertices, Matrix4.Identity, false, false); } //!!!!тут? //render axes of objects if (!drawShadows && Owner.Objects.Count <= 30) { foreach (TransformToolObject gizmoObject in Owner.Objects) { var size = radius / 3; double alpha = 1; // 0.333; double thickness = GetLineWorldThickness(gizmoObject.Position); Matrix4 transform = new Matrix4(gizmoObject.Rotation.ToMatrix3() * Matrix3.FromScale(new Vector3(size, size, size)), gizmoObject.Position); var headHeight = size / 4; DebugGeometry.SetColor(new ColorValue(1, 0, 0, alpha), false); //, true ); DebugGeometry.AddArrow(transform * Vector3.Zero, transform * Vector3.XAxis, headHeight, 0, true, thickness); DebugGeometry.SetColor(new ColorValue(0, 1, 0, alpha), false); //, true ); DebugGeometry.AddArrow(transform * Vector3.Zero, transform * Vector3.YAxis, headHeight, 0, true, thickness); DebugGeometry.SetColor(new ColorValue(0, 0, 1, alpha), false); //, true ); DebugGeometry.AddArrow(transform * Vector3.Zero, transform * Vector3.ZAxis, headHeight, 0, true, thickness); } } //Inner circle { List <Vector3> points = new List <Vector3>(64); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position; pos += cameraRight * Math.Cos(angle) * innerRadius; pos += CameraSettings.Up * Math.Sin(angle) * innerRadius; points.Add(pos); } if (!drawShadows) { DebugGeometry.SetColor(darkGray, false); //, true ); } AddPolygonalChain(points.ToArray(), lineThickness, drawShadowsFactor); } //if( !drawShadows ) // DebugGeometry.Color = darkGray; //for( double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step ) //{ // Vec3 pos = position; // pos += cameraRight * Math.Cos( angle ) * innerRadius; // pos += camera.Up * Math.Sin( angle ) * innerRadius; // if( angle != 0 ) // AddLine( oldPos, pos, lineThickness, drawShadows ); // oldPos = pos; //} //Radius if (!Owner.SceneMode2D) { List <Vector3> points = new List <Vector3>(64); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position; pos += cameraRight * Math.Cos(angle) * radius; pos += CameraSettings.Up * Math.Sin(angle) * radius; points.Add(pos); } if (!drawShadows) { DebugGeometry.SetColor((axis == Axis.Radius) ? yellow : gray, false); //, true ); } AddPolygonalChain(points.ToArray(), lineThickness, drawShadowsFactor); } //if( !drawShadows ) // DebugGeometry.Color = ( axis == Axis.Radius ) ? yellow : gray; //for( double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step ) //{ // Vec3 pos = position; // pos += cameraRight * Math.Cos( angle ) * radius; // pos += camera.Up * Math.Sin( angle ) * radius; // if( angle != 0 ) // AddLine( oldPos, pos, lineThickness, drawShadows ); // oldPos = pos; //} //X { List <Vector3> points = new List <Vector3>(64); List <bool> skipLines = new List <bool>(64); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position + startRotation * (new Vector3(0, Math.Sin(angle), Math.Cos(angle)) * innerRadius); points.Add(pos); bool skip = GetCameraDistance(pos) > cameraDistance; skipLines.Add(skip); //if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // points.Add( pos ); } if (!drawShadows) { DebugGeometry.SetColor((axis == Axis.X) ? yellow : red, false); //, true ); } List <Vector3> newPoints = new List <Vector3>(64); for (int n = 0; n < points.Count; n++) { if (!skipLines[n]) { newPoints.Add(points[n]); } else { if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } } if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } //for( double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step ) //{ // Vec3 pos = position + startRotation * ( new Vec3( 0, Math.Sin( angle ), // Math.Cos( angle ) ) * innerRadius ); // if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // AddLine( oldPos, pos, lineThickness, drawShadows ); // oldPos = pos; //} //Y { List <Vector3> points = new List <Vector3>(64); List <bool> skipLines = new List <bool>(64); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position + startRotation * (new Vector3(Math.Sin(angle), 0, Math.Cos(angle)) * innerRadius); points.Add(pos); bool skip = GetCameraDistance(pos) > cameraDistance; skipLines.Add(skip); //if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // points.Add( pos ); } if (!drawShadows) { DebugGeometry.SetColor((axis == Axis.Y) ? yellow : green, false); //, true ); } List <Vector3> newPoints = new List <Vector3>(64); for (int n = 0; n < points.Count; n++) { if (!skipLines[n]) { newPoints.Add(points[n]); } else { if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } } if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } //if( !drawShadows ) // DebugGeometry.Color = ( axis == Axis.Y ) ? yellow : green; //for( double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step ) //{ // Vec3 pos = position + startRotation * ( new Vec3( Math.Sin( angle ), 0, // Math.Cos( angle ) ) * innerRadius ); // if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // AddLine( oldPos, pos, lineThickness, drawShadows ); // oldPos = pos; //} //Z { List <Vector3> points = new List <Vector3>(64); List <bool> skipLines = new List <bool>(64); for (double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step) { Vector3 pos = position + startRotation * (new Vector3(Math.Sin(angle), Math.Cos(angle), 0) * innerRadius); points.Add(pos); bool skip = GetCameraDistance(pos) > cameraDistance; if (Owner.SceneMode2D) { skip = false; } skipLines.Add(skip); //if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // points.Add( pos ); } if (!drawShadows) { DebugGeometry.SetColor((axis == Axis.Z) ? yellow : blue, false); //, true ); } List <Vector3> newPoints = new List <Vector3>(64); for (int n = 0; n < points.Count; n++) { if (!skipLines[n]) { newPoints.Add(points[n]); } else { if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } } if (newPoints.Count != 0) { AddPolygonalChain(newPoints.ToArray(), lineThickness, drawShadowsFactor); newPoints.Clear(); } } //if( !drawShadows ) // DebugGeometry.Color = ( axis == Axis.Z ) ? yellow : blue; //for( double angle = 0; angle <= MathEx.PI * 2 + step * .5f; angle += step ) //{ // Vec3 pos = position + startRotation * ( new Vec3( Math.Sin( angle ), // Math.Cos( angle ), 0 ) * innerRadius ); // if( angle != 0 && GetCameraDistance( pos ) <= cameraDistance ) // AddLine( oldPos, pos, lineThickness, drawShadows ); // oldPos = pos; //} //Arrows if (axis != Axis.None && axis != Axis.InnerCircle) { Plane plane = new Plane(); switch (axis) { case Axis.X: plane = Plane.FromPointAndNormal(position, GetStartObjectsRotation() * Vector3.XAxis); break; case Axis.Y: plane = Plane.FromPointAndNormal(position, GetStartObjectsRotation() * Vector3.YAxis); break; case Axis.Z: plane = Plane.FromPointAndNormal(position, GetStartObjectsRotation() * Vector3.ZAxis); break; case Axis.Radius: plane = Plane.FromPointAndNormal(position, CameraSettings.Direction); break; } Vector2 mouse; if (modify_Activated || initialObjectsTransform != null) { mouse = mouseStartPosition; } else { mouse = Viewport.MousePosition; } Ray ray = CameraSettings.GetRayByScreenCoordinates(mouse); Vector3 planeIntersection; if (plane.Intersects(ray, out planeIntersection)) { Vector3 direction = (planeIntersection - position).GetNormalize(); Vector3 arrowCenter; if (axis == Axis.Radius) { arrowCenter = position + direction * radius; } else { arrowCenter = position + direction * innerRadius; } double arrowLength = radius * .3f; Vector3 tangent = Vector3.Cross(direction, plane.Normal); Vector3 arrowPosition1 = arrowCenter + tangent * arrowLength; Vector3 arrowPosition2 = arrowCenter - tangent * arrowLength; if (!drawShadows) { DebugGeometry.SetColor(yellow, false); //, true ); } { Vector3 direction1 = (arrowPosition1 - arrowCenter).GetNormalize(); AddCone( arrowCenter + direction1 * arrowLength / 2, arrowPosition1, arrowLength / 8, lineThickness, drawShadowsFactor); } { Vector3 direction2 = (arrowPosition2 - arrowCenter).GetNormalize(); AddCone( arrowCenter + direction2 * arrowLength / 2, arrowPosition2, arrowLength / 8, lineThickness, drawShadowsFactor); } } } } //DebugGeometry.RestoreDefaultDepthSettings(); }
public override void OnMouseMove(Vector2 mouse) { base.OnMouseMove(mouse); if (modify_Activated && !Viewport.MouseRelativeMode) { UpdateCursorTransitionOnScreenBorder(); Vector2 viewportSize = Owner.ViewportControl.Viewport.SizeInPixels.ToVector2(); Vector2 mousePosition = mouse + cursorTransitionOnScreenBorderOffset / viewportSize; Vector2 screenPosition = mousePosition - startMouseOffset; Ray ray = CameraSettings.GetRayByScreenCoordinates(screenPosition); Vector3 position = modifyPosition; double size = GetSize(); if (size == 0) { return; } Vector3 xOffset, yOffset, zOffset; GetAxisOffsets(out xOffset, out yOffset, out zOffset); double offset = 0; if (!double.IsNaN(ray.Direction.X)) { Vector2 pixelOffset = (mousePosition - startMousePosition) * viewportSize; double mouseOffsetAngle = Math.Atan2(-pixelOffset.Y, pixelOffset.X); if (selectedAxes.TrueCount == 3) { offset = mousePosition.Y - startMousePosition.Y; offset *= -1; offset *= viewportSize.Y; } else { Vector2 screenModifyPosition; if (CameraSettings.ProjectToScreenCoordinates(modifyPosition, out screenModifyPosition)) { screenModifyPosition *= viewportSize; offset = 0; if (selectedAxes.x) { Vector2 screenXPosition; CameraSettings.ProjectToScreenCoordinates(position + xOffset, out screenXPosition); if (screenXPosition.X != 0 && screenXPosition.Y != 0) { screenXPosition *= viewportSize; Vector2 diff = screenXPosition - screenModifyPosition; double diffAngle = Math.Atan2(-diff.Y, diff.X); double angle = mouseOffsetAngle - diffAngle; angle = MathEx.RadianNormalize360(angle); double off = Math.Cos(angle) * pixelOffset.Length(); offset += off; } } if (selectedAxes.y) { Vector2 screenYPosition; CameraSettings.ProjectToScreenCoordinates(position + yOffset, out screenYPosition); if (screenYPosition.X != 0 && screenYPosition.Y != 0) { screenYPosition *= viewportSize; Vector2 diff = screenYPosition - screenModifyPosition; double diffAngle = Math.Atan2(-diff.Y, diff.X); double angle = mouseOffsetAngle - diffAngle; angle = MathEx.RadianNormalize360(angle); double off = Math.Cos(angle) * pixelOffset.Length(); offset += off; } } if (selectedAxes.z) { Vector2 screenZPosition; CameraSettings.ProjectToScreenCoordinates(position + zOffset, out screenZPosition); if (screenZPosition.X != 0 && screenZPosition.Y != 0) { screenZPosition *= viewportSize; Vector2 diff = screenZPosition - screenModifyPosition; double diffAngle = Math.Atan2(-diff.Y, diff.X); double angle = mouseOffsetAngle - diffAngle; angle = MathEx.RadianNormalize360(angle); double off = Math.Cos(angle) * pixelOffset.Length(); offset += off; } } } } const double scaleCoefficient = .01f; offset *= scaleCoefficient; double coef; if (offset > 0) { double snap = Owner.GetSnapScale(); if (snap != 0) { offset += snap / 2; offset /= snap; offset = (int)offset; offset *= snap; } coef = offset + 1.0f; } else { double snap = Owner.GetSnapScale(); if (snap != 0) { offset -= snap / 2; offset /= snap; offset = (int)offset; offset *= snap; } coef = 1.0f / (1.0f - offset); } Vector3 scaleOffset = new Vector3(selectedAxes.x ? coef : 1, selectedAxes.y ? coef : 1, selectedAxes.z ? coef : 1); //update objects if (initialObjectsTransform != null && Owner.Objects.Count == initialObjectsTransform.Length) { Owner.OnScaleModeUpdateObjects(initialObjectsTransform, modifyPosition, scaleOffset); } helpText = string.Format("[{0} {1} {2}]", scaleOffset.X.ToString("F2"), scaleOffset.Y.ToString("F2"), scaleOffset.Z.ToString("F2")); } } }