public void OnEdit(IChiselHandles handles) { // Store our allocated handles in generatorState to avoid reallocating them every frame var cylinderHandles = handles.generatorState as CylinderHandles; if (cylinderHandles == null) { cylinderHandles = new CylinderHandles(); cylinderHandles.Init(handles, this); handles.generatorState = cylinderHandles; } cylinderHandles.Update(handles, this); // Render vertical lines at the horizon of the cylinder handles.DoRenderHandles(new[] { cylinderHandles.verticalHandle1, cylinderHandles.verticalHandle2 }); // Move the cylinder top/bottom up/down var prevModified = handles.modified; { handles.DoSlider1DHandle(ref cylinderHandles.bottomPoint, -cylinderHandles.normal, cylinderHandles.bottomHandles); var haveFocus = handles.lastHandleHadFocus; handles.DoSlider1DHandle(ref cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topHandles); haveFocus = haveFocus || handles.lastHandleHadFocus; if (haveFocus) { handles.RenderDistanceMeasurement(cylinderHandles.topPoint, cylinderHandles.bottomPoint, Mathf.Abs(height)); } } if (prevModified != handles.modified) { cylinderHandles.topY = Vector3.Dot(Vector3.up, cylinderHandles.topPoint); cylinderHandles.bottomY = Vector3.Dot(Vector3.up, cylinderHandles.bottomPoint); height = cylinderHandles.topY - cylinderHandles.bottomY; bottomOffset = cylinderHandles.bottomY; } // Resize the top/bottom circle by grabbing and dragging it prevModified = handles.modified; { // Make the bottom circle draggable DraggableRadius(handles, ref bottomDiameterX, ref bottomDiameterZ, cylinderHandles.bottomPoint, -cylinderHandles.normal, cylinderHandles.bottomXVector, cylinderHandles.bottomZVector, cylinderHandles.bottomRadiusHandles, this.isEllipsoid); // If we're a Cylinder, the top circle actually changes the bottom circle too if (type == CylinderShapeType.Cylinder) { DraggableRadius(handles, ref bottomDiameterX, ref bottomDiameterZ, cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topXVector, cylinderHandles.topZVector, cylinderHandles.topRadiusHandles, this.isEllipsoid); } else // If we're a Conical Frustum, the top circle can be resized independently from the bottom circle if (type == CylinderShapeType.ConicalFrustum) { DraggableRadius(handles, ref topDiameterX, ref topDiameterZ, cylinderHandles.topPoint, cylinderHandles.normal, cylinderHandles.topXVector, cylinderHandles.topZVector, cylinderHandles.topRadiusHandles, this.isEllipsoid); } // else; If we're a Cone, we ignore the top circle } if (prevModified != handles.modified) { // Ensure that when our shape is circular and we modify it, that when we convert back to an ellipsoid, it'll still be circular if (!this.isEllipsoid) { topDiameterZ = topDiameterX; bottomDiameterZ = bottomDiameterX; } } }
// // TODO: code below needs to be cleaned up & simplified // static void DraggableRadius(IChiselHandles handles, ref float diameterX, ref float diameterZ, Vector3 center, Vector3 up, Vector3 xVector, Vector3 zVector, IChiselHandle[] radiusHandles, bool isEllipsoid) { if (isEllipsoid) { Debug.Assert(radiusHandles.Length == 4); diameterX = -diameterX; handles.DoSlider1DHandle(ref diameterX, center, xVector, radiusHandles[1]); // right if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterX = -diameterX; handles.DoSlider1DHandle(ref diameterX, center, xVector, radiusHandles[0]); // left if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterZ = -diameterZ; handles.DoSlider1DHandle(ref diameterZ, center, zVector, radiusHandles[3]); // back if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterZ = -diameterZ; handles.DoSlider1DHandle(ref diameterZ, center, zVector, radiusHandles[2]); // forward if (handles.lastHandleHadFocus) { var radiusX = diameterX * 0.5f; var radiusZ = diameterZ * 0.5f; var vecX = (xVector.normalized * radiusX); var vecZ = (zVector.normalized * radiusZ); handles.RenderDistanceMeasurement(center, center + vecX, radiusX); handles.RenderDistanceMeasurement(center, center + vecZ, radiusZ); } diameterX = Mathf.Abs(diameterX); diameterZ = Mathf.Abs(diameterZ); } else { Debug.Assert(radiusHandles.Length == 1); handles.DoDistanceHandle(ref diameterX, center, up, radiusHandles[0]); // left diameterX = Mathf.Abs(diameterX); var radiusX = diameterX * 0.5f; if (handles.lastHandleHadFocus) { if (handles.TryGetClosestPoint(radiusHandles, out var closestPoint, interpolate: false)) { var vec = (closestPoint - center); handles.RenderDistanceMeasurement(center, center + vec, radiusX); } } } }