public AxisAlignedBox3f GetPrintMeshesBounds(bool bPrecise) { AxisAlignedBox3f b = AxisAlignedBox3f.Empty; foreach (PrintMeshSO so in PrintMeshes) { if (SceneUtil.IsVisible(so) == false) { continue; } if (bPrecise) { var xform = SceneTransforms.ObjectToSceneXForm(so); foreach (Vector3d v in so.Mesh.Vertices()) { b.Contain((Vector3f)xform.TransformP(v)); } } else { Box3f sobox = so.GetBoundingBox(CoordSpace.SceneCoords); if (sobox.Volume > 0) { foreach (Vector3d v in sobox.VerticesItr()) { b.Contain(v); } } } } return(b); }
public virtual bool FindNearest(Vector3d point, double maxDist, out SORayHit nearest, CoordSpace eInCoords) { nearest = null; // convert to local Vector3f local_pt = SceneTransforms.TransformTo((Vector3f)point, this, eInCoords, CoordSpace.ObjectCoords); AxisAlignedBox3f bounds = GetLocalBoundingBox(); float local_dist = bounds.Distance(local_pt); float dist_incoords = SceneTransforms.TransformTo(local_dist, this, CoordSpace.ObjectCoords, eInCoords); if (dist_incoords > maxDist) { return(false); } nearest = new SORayHit(); nearest.fHitDist = dist_incoords; Vector3f nearPt = bounds.NearestPoint(local_pt); nearest.hitPos = SceneTransforms.TransformTo(nearPt, this, CoordSpace.ObjectCoords, eInCoords); nearest.hitNormal = Vector3f.Zero; nearest.hitGO = RootGameObject; nearest.hitSO = this; return(true); }
//new Bounds(Vector3.zero, new Vector3(-1.31337f, -1.31337f, -1.31337f)); public static AxisAlignedBox3f GetBoundingBox(GameObject go) { Renderer r = go.GetComponent <Renderer>(); if (r != null) { return(r.bounds); } else if (go.HasChildren()) { AxisAlignedBox3f b = InvalidBounds; int i = 0; foreach (GameObject child_go in go.Children()) { if (i++ == 0) { b = GetBoundingBox(child_go); } else { b.Contain(GetBoundingBox(child_go)); } } return(b); } else { return(new AxisAlignedBox3f(go.transform.position, new Vector3(0.001f, 0.001f, 0.001f))); } }
void update_measurement() { Frame3f localFrame = meshTarget.GetLocalFrame(CoordSpace.ObjectCoords); Vector3f localP = localFrame.ToFrameP(scene.ToSceneP(measureHitPos)); AxisAlignedBox3f bounds = meshTarget.GetLocalBoundingBox(); Vector3f dv = localP - bounds.Center; dv.y = 0; Line3f line = new Line3f(Vector3f.Zero, Vector3f.AxisY); Vector3f linePos = line.ClosestPoint(localP); Frame3f mFrame = new Frame3f(linePos, Vector3f.AxisY); MeshSO.SectionInfo info = meshTarget.MeasureSection(mFrame); curDimension = info.maxDiameter; Vector3f center = 0.5f * (info.maxDiamPos1 + info.maxDiamPos2); //measureAxisPos = scene.ToWorldP(localFrame.FromFrameP(linePos)); displayPosS = localFrame.FromFrameP(linePos); circleCenterS = localFrame.FromFrameP(center); maxStart = localFrame.FromFrameP(info.maxDiamPos1); maxEnd = localFrame.FromFrameP(info.maxDiamPos2); }
public BoundingBox(Vector3 min, Vector3 max) { Minimum = min; Maximum = max; boxf = new AxisAlignedBox3f(Minimum.X, Minimum.Y, Minimum.Z, Maximum.X, Maximum.Y, Maximum.Z); boxd = new AxisAlignedBox3d(Minimum.X, Minimum.Y, Minimum.Z, Maximum.X, Maximum.Y, Maximum.Z); corners = null; }
override public AxisAlignedBox3f GetLocalBoundingBox() { AxisAlignedBox3f b = (AxisAlignedBox3f)meshGO.GetSharedMesh().bounds; Vector3f scale = parentGO.GetLocalScale(); b.Scale(scale.x, scale.y, scale.z); return(b); }
internal BoundingBox(AxisAlignedBox3d box3d) { Minimum = box3d.Min.ToVector3(); Maximum = box3d.Max.ToVector3(); boxf = new AxisAlignedBox3f(Minimum.X, Minimum.Y, Minimum.Z, Maximum.X, Maximum.Y, Maximum.Z); boxd = box3d; corners = null; }
BoundingBox(Vector3 min, Vector3 max, AxisAlignedBox3f box3F) { Minimum = min; Maximum = max; boxf = box3F; boxd = boxf; corners = null; }
internal AxisAlignedBox(AxisAlignedBox3d box3d) { Minimum = box3d.Min.ToVector3(); Maximum = box3d.Max.ToVector3(); boxf = new AxisAlignedBox3f(Minimum.X, Minimum.Y, Minimum.Z, Maximum.X, Maximum.Y, Maximum.Z); boxd = box3d; Center = box3d.Center.ToVector3(); Dimensions = Maximum - Minimum; Diagonal = Dimensions.Length(); }
public AxisAlignedBox(Vector3 minimum, Vector3 maximum) { Minimum = minimum; Maximum = maximum; Center = (Maximum + Minimum) / 2f; Dimensions = Maximum - Minimum; Diagonal = Dimensions.Length(); boxf = new AxisAlignedBox3f(Minimum.X, Minimum.Y, Minimum.Z, Maximum.X, Maximum.Y, Maximum.Z); boxd = boxf; }
/// <summary> /// get combined MeshFilter bounding box of objects /// </summary> public static AxisAlignedBox3f GetGeometryBoundingBox(List <fGameObject> objects, bool bIncludeChildren = false) { AxisAlignedBox3f b = AxisAlignedBox3f.Empty; foreach (fGameObject go in objects) { b.Contain(GetGeometryBoundingBox(go, bIncludeChildren)); } return(b); }
public static AxisAlignedBox3f BoundsInFrame(Mesh m, Frame3f f) { AxisAlignedBox3f box = AxisAlignedBox3f.Empty; int N = m.vertexCount; for (int k = 0; k < N; ++k) { box.Contain(f.ToFrameP(m.vertices[k])); } return(box); }
/// <summary> /// recomputes clipping bounds for scene. Still probably needs some work... /// </summary> public static void UpdateViewClippingBounds() { AxisAlignedBox3f worldBounds = CC.Objects.GetPrintMeshesBounds(false); float bed_dim = (float)MathUtil.Max(CC.Settings.BedSizeXMM, CC.Settings.BedSizeYMM, CC.Settings.BedSizeZMM); float maxdim = Math.Max(worldBounds.MaxDim, bed_dim); float fVertFOV = FPlatform.MainCamera.VertFieldOfViewDeg; float dist = maxdim / (float)Math.Tan(0.5f * fVertFOV * MathUtil.Deg2Radf); dist *= 10; CC.ActiveContext.CameraManager.UpdateMainCamFarDistance(dist); }
public void SelectionBoundingBox(ref AxisAlignedBox3f box) { StoredCommands sc = new StoredCommands(); uint key = sc.AppendQueryCommand_GetBoundingBox(); ExecuteCommands(sc); floatArray min = new floatArray(3), max = new floatArray(3); sc.GetQueryResult_GetBoundingBox(key, min.cast(), max.cast()); box.Min.Set(min); box.Max.Set(max); }
public static AxisAlignedBox3f GetBoundingBox(List <GameObject> objects) { if (objects.Count == 0) { return(InvalidBounds); } AxisAlignedBox3f b = GetBoundingBox(objects[0]); for (int i = 1; i < objects.Count; ++i) { b.Contain(GetBoundingBox(objects[i])); } return(b); }
// will return InvalidBounds if any element in list doesn't have a mesh public static AxisAlignedBox3f GetGeometryBoundingBox(List <GameObject> objects) { if (objects.Count == 0) { return(InvalidBounds); } AxisAlignedBox3f b = GetGeometryBoundingBox(objects[0]); foreach (GameObject go in objects) { b.Contain(GetGeometryBoundingBox(go)); } return(b); }
private void queriesButton_Click(object sender, EventArgs e) { mm.RemoteControl rc = new mm.RemoteControl(); rc.Initialize(); AxisAlignedBox3f bounds = new AxisAlignedBox3f(); rc.SelectionBoundingBox(ref bounds); Vector3f Min = bounds.Min, Max = bounds.Max; outputTextBox.Text = String.Format("Bounding Box [{0},{1},{2}] [{3},{4},{5}]", Min[0], Min[1], Min[2], Max[0], Max[1], Max[2]); rc.Shutdown(); }
// knows about our magic invalid value public static AxisAlignedBox3f Combine(AxisAlignedBox3f b1, AxisAlignedBox3f b2) { if (b1 == InvalidBounds) { return(b2); } else if (b2 == InvalidBounds) { return(b1); } AxisAlignedBox3f r = b1; r.Contain(b2); return(r); }
/// <summary> /// Get MeshFilter bounding box of GO. If bIncludeChildren = true, descend /// into children and return union of boxes /// </summary> public static AxisAlignedBox3f GetGeometryBoundingBox(GameObject go, bool bIncludeChildren = false) { MeshFilter f = go.GetComponent <MeshFilter>(); AxisAlignedBox3f b = (f != null) ? (AxisAlignedBox3f)f.mesh.bounds : AxisAlignedBox3f.Empty; if (bIncludeChildren && go.HasChildren()) { foreach (GameObject child_go in go.Children()) { AxisAlignedBox3f child_b = GetGeometryBoundingBox(child_go, true); b.Contain(child_b); } } return(b); }
/// <summary> /// Compute AABB of scene in given space. Note that this will *not* be the same box /// in world space as in scene space. /// This computation ignores SOs with zero volume. /// </summary> public AxisAlignedBox3f GetBoundingBox(CoordSpace eSpace, bool bIncludeBoundsObjects) { if (eSpace == CoordSpace.ObjectCoords) { eSpace = CoordSpace.SceneCoords; } AxisAlignedBox3f b = AxisAlignedBox3f.Empty; foreach (SceneObject so in SceneObjects) { Box3f sobox = so.GetBoundingBox(eSpace); if (sobox.Volume > 0) { foreach (Vector3d v in sobox.VerticesItr()) { b.Contain(v); } } } if (bIncludeBoundsObjects) { AxisAlignedBox3f sceneBounds = UnityUtil.GetGeometryBoundingBox(BoundsObjects, true); if (sceneBounds.Volume > 0) { if (eSpace == CoordSpace.WorldCoords) { for (int k = 0; k < 8; ++k) { b.Contain(ToWorldP(sceneBounds.Corner(k))); } } else { b.Contain(sceneBounds); } } } if (b.Volume == 0) { b = new AxisAlignedBox3f(1.0f); } return(b); }
public static Bounds GetLocalBoundingBox(IEnumerable <SceneObject> vObjects) { int i = 0; AxisAlignedBox3f b = AxisAlignedBox3f.Infinite; foreach (SceneObject so in vObjects) { if (i == 0) { b = so.GetLocalBoundingBox(); } else { b.Contain(so.GetLocalBoundingBox()); } } return(b); }
public AxisAlignedBox3f GetBoundingBox(bool bIncludeBoundsObjects) { AxisAlignedBox3f b = UnityUtil.InvalidBounds; foreach (SceneObject so in SceneObjects) { b.Contain(so.GetTransformedBoundingBox()); } if (b == UnityUtil.InvalidBounds || bIncludeBoundsObjects) { UnityUtil.Combine(b, UnityUtil.GetBoundingBox(BoundsObjects)); } if (b == UnityUtil.InvalidBounds) { b.Contain(Vector3f.Zero); b.Expand(1.0f); } return(b); }
public DMeshSO BuildSO(FScene scene, SOMaterial material) { DMesh3 revolveMesh = UnityUtil.UnityMeshToDMesh(meshObject.GetSharedMesh(), false); // move axis frame to center of bbox of mesh, measured in axis frame Frame3f useF = OutputFrame; AxisAlignedBox3f boundsInFrame = (AxisAlignedBox3f)BoundsUtil.BoundsInFrame(revolveMesh.Vertices(), useF); useF.Origin = useF.FromFrameP(boundsInFrame.Center); // transform mesh into this frame MeshTransforms.ToFrame(revolveMesh, useF); // create new so DMeshSO meshSO = new DMeshSO(); meshSO.Create(revolveMesh, material); meshSO.SetLocalFrame(useF, CoordSpace.ObjectCoords); return(meshSO); }
public static void RecenterAboveOrigin(FScene scene, SceneObject so, bool bInteractive) { Frame3f curFrameO = so.GetLocalFrame(CoordSpace.ObjectCoords); AxisAlignedBox3f bounds = so.GetLocalBoundingBox(); Box3f box = new Box3f(bounds); box = curFrameO.FromFrame(ref box); AxisAlignedBox3f boundsS = box.ToAABB(); Vector3f c = boundsS.Center - 0.5f * boundsS.Height * Vector3f.AxisY; Vector3f dt = -c; if (dt.MaxAbs > MathUtil.ZeroTolerancef) { Frame3f newFrameO = curFrameO.Translated(dt); TransformSOChange change = new TransformSOChange(so, curFrameO, newFrameO, CoordSpace.ObjectCoords); scene.History.PushChange(change, false); if (bInteractive) { scene.History.PushInteractionCheckpoint(); } } }
private void update_slice_height_gizmo() { if (CurrentToolpaths == null) { if (SliceHeightGizmo != null && SceneUtil.IsVisible(SliceHeightGizmo)) { SceneUtil.SetVisible(SliceHeightGizmo, false); } slice_gizmo_valid = false; return; } if (slice_gizmo_valid) { return; } AxisAlignedBox3f bounds = GetPrintMeshesBounds(true); if (bounds == AxisAlignedBox3f.Empty) { return; // will be rectified next frame? } int nSlices = CurrentToolpaths.GetSlices().Count; PlanarSliceStack slices = CurrentToolpaths.GetSlices(); // line is floating //bounds.Min.y = (float)slices[0].Z; //bounds.Max.y = (float)slices[slices.Count - 1].Z; // line at ground bounds.Min.y = 0; bounds.Max.y = (float)(slices[slices.Count - 1].Z - slices[0].Z); Vector3f basePos = new Vector3f(bounds.Max.x, bounds.Min.y, bounds.Max.z); basePos.x += 10; basePos.z += 10; Vector3f topPos = basePos + bounds.Height * Vector3f.AxisY; if (SliceHeightGizmo == null) { SliceHeightGizmo = new SlicePlaneHeightSO() { LineAlwaysVisible = false }; SliceHeightGizmo.Create(CC.ActiveScene.PivotSOMaterial, null); SliceHeightGizmo.DisableShadows(); CC.ActiveScene.AddSceneObject(SliceHeightGizmo); SliceHeightGizmo.Name = "Slice_Height"; SliceHeightGizmo.ConstraintFrameS = new Frame3f(basePos); SliceHeightGizmo.SetLocalFrame(SliceHeightGizmo.ConstraintFrameS, CoordSpace.SceneCoords); SliceHeightGizmo.MinPosS = basePos; SliceHeightGizmo.MaxPosS = topPos; SliceHeightGizmo.CenterPosS = bounds.Point(0, -1, 0); SliceHeightGizmo.BoundsDim = (float)Math.Max(bounds.Width, bounds.Depth) + 10.0f; SliceHeightGizmo.OnTransformModified += SliceHeightGizmo_OnTransformModified; SliceHeightGizmo.InitializeLiveGizmo(CC.ActiveScene); } if (SceneUtil.IsVisible(SliceHeightGizmo) == false) { SceneUtil.SetVisible(SliceHeightGizmo, true); } SliceHeightGizmo.ConstraintFrameS = new Frame3f(basePos); ignore_xform_event = true; SliceHeightGizmo.SetLocalFrame(SliceHeightGizmo.ConstraintFrameS, CoordSpace.SceneCoords); ignore_xform_event = false; SliceHeightGizmo.MinPosS = basePos; SliceHeightGizmo.MaxPosS = topPos; SliceHeightGizmo.CenterPosS = bounds.Point(0, -1, 0); SliceHeightGizmo.BoundsDim = (float)Math.Max(bounds.Width, bounds.Depth) + 10.0f; set_slice_height_from_layer(); slice_gizmo_valid = true; }
public static fTextAreaGameObject CreateTextAreaGO( string sName, string sText, Colorf textColor, float fTextHeight, Vector2f areaDimensions, HorizontalAlignment alignment = HorizontalAlignment.Left, BoxPosition textOrigin = BoxPosition.Center, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshPro tm = textGO.AddComponent <TextMeshPro>(); //tm.isOrthographic = false; switch (alignment) { case HorizontalAlignment.Left: tm.alignment = TextAlignmentOptions.TopLeft; break; case HorizontalAlignment.Center: tm.alignment = TextAlignmentOptions.Center; break; case HorizontalAlignment.Right: tm.alignment = TextAlignmentOptions.TopRight; break; } tm.enableWordWrapping = true; tm.autoSizeTextContainer = false; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); TextContainer container = textGO.GetComponent <TextContainer>(); container.isAutoFitting = false; container.anchorPosition = TextContainerAnchors.TopLeft; if (alignment != HorizontalAlignment.Left) { throw new NotSupportedException("CreateTextAreaGO: currently only Left-aligned text is supported"); } //switch ( alignment ) { // case HorizontalAlignment.Left: // container.anchorPosition = TextContainerAnchors.TopLeft; break; // case HorizontalAlignment.Center: // container.anchorPosition = TextContainerAnchors.Middle; break; // case HorizontalAlignment.Right: // container.anchorPosition = TextContainerAnchors.TopRight; break; //} tm.ForceMeshUpdate(); // set container width and height to just contain text AxisAlignedBox3f bounds = tm.bounds; Vector2f size = new Vector2f(bounds.Width, bounds.Height); // Now we want to scale text to hit our target height, but if we scale by size.y // then the scaling will vary by text height (eg "m" will get same height as "My"). // However: 1) size.y varies with tm.fontSize, but it's not clear how. // 2) fontInfo.LineHeight tells us the height we want but doesn't change w/ tm.fontSize // I tried a few values and the relationship is linear. It is in the ballpark // of just being 10x...actually closer to 11x. No other values in fontInfo have a nice // round-number relationship. But this value is probably font-dependent!! float t = tm.fontSize / tm.font.fontInfo.LineHeight; float magic_k = 10.929f; // [RMS] solve-for-x given a few different fontSize values float font_size_y = magic_k * t; float fScaleH = fTextHeight / font_size_y; tm.transform.localScale = new Vector3(fScaleH, fScaleH, fScaleH); float fTextWidth = fScaleH * size.x; // set container size now that we know text scaling factor container.width = areaDimensions.x / fScaleH; container.height = areaDimensions.y / fScaleH; // by default text origin is top-left if (textOrigin == BoxPosition.Center) { tm.transform.Translate(-fTextWidth / 2.0f, fTextHeight / 2.0f, fOffsetZ); } else if (textOrigin == BoxPosition.BottomLeft) { tm.transform.Translate(0, fTextHeight, fOffsetZ); } else if (textOrigin == BoxPosition.TopRight) { tm.transform.Translate(-fTextWidth, 0, fOffsetZ); } else if (textOrigin == BoxPosition.BottomRight) { tm.transform.Translate(-fTextWidth, fTextHeight, fOffsetZ); } else if (textOrigin == BoxPosition.CenterLeft) { tm.transform.Translate(0, fTextHeight / 2.0f, fOffsetZ); } else if (textOrigin == BoxPosition.CenterRight) { tm.transform.Translate(-fTextWidth, fTextHeight / 2.0f, fOffsetZ); } else if (textOrigin == BoxPosition.CenterTop) { tm.transform.Translate(-fTextWidth / 2.0f, 0, fOffsetZ); } else if (textOrigin == BoxPosition.CenterBottom) { tm.transform.Translate(-fTextWidth / 2.0f, fTextHeight, fOffsetZ); } textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; return(new fTextAreaGameObject(textGO, new fText(tm, TextType.TextMeshPro), areaDimensions)); //new Vector2f(fTextWidth, fTextHeight) ); }
// [TODO] currently only allows for left-justified text. // Can support center/right, but the translate block needs to be rewritten // (can we generalize as target-center of 2D bbox?? public static fTextGameObject CreateTextMeshProGO( string sName, string sText, Colorf textColor, float fTextHeight, BoxPosition textOrigin = BoxPosition.Center, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshProExt tm = textGO.AddComponent <TextMeshProExt>(); //tm.isOrthographic = false; tm.alignment = TextAlignmentOptions.TopLeft; tm.enableWordWrapping = false; tm.autoSizeTextContainer = true; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); TextContainer container = textGO.GetComponent <TextContainer>(); container.isAutoFitting = true; container.anchorPosition = TextContainerAnchors.TopLeft; if (textOrigin == BoxPosition.Center) { container.anchorPosition = TextContainerAnchors.Middle; tm.alignment = TextAlignmentOptions.Center; } else if (textOrigin == BoxPosition.BottomLeft) { container.anchorPosition = TextContainerAnchors.BottomLeft; tm.alignment = TextAlignmentOptions.BottomLeft; } else if (textOrigin == BoxPosition.TopRight) { container.anchorPosition = TextContainerAnchors.TopRight; tm.alignment = TextAlignmentOptions.TopRight; } else if (textOrigin == BoxPosition.BottomRight) { container.anchorPosition = TextContainerAnchors.BottomRight; tm.alignment = TextAlignmentOptions.BottomRight; } else if (textOrigin == BoxPosition.CenterLeft) { container.anchorPosition = TextContainerAnchors.Left; tm.alignment = TextAlignmentOptions.Left; } else if (textOrigin == BoxPosition.CenterRight) { container.anchorPosition = TextContainerAnchors.Right; tm.alignment = TextAlignmentOptions.Right; } else if (textOrigin == BoxPosition.CenterTop) { container.anchorPosition = TextContainerAnchors.Top; tm.alignment = TextAlignmentOptions.Top; } else if (textOrigin == BoxPosition.CenterBottom) { container.anchorPosition = TextContainerAnchors.Bottom; tm.alignment = TextAlignmentOptions.Bottom; } tm.ForceMeshUpdate(); // set container width and height to just contain text AxisAlignedBox3f bounds = tm.bounds; Vector2f size = new Vector2f(bounds.Width, bounds.Height); container.width = size.x + 1; container.height = size.y + 1; // Now we want to scale text to hit our target height, but if we scale by size.y // then the scaling will vary by text height (eg "m" will get same height as "My"). // However: 1) size.y varies with tm.fontSize, but it's not clear how. // 2) fontInfo.LineHeight tells us the height we want but doesn't change w/ tm.fontSize // I tried a few values and the relationship is linear. It is in the ballpark // of just being 10x...actually closer to 11x. No other values in fontInfo have a nice // round-number relationship. But this value is probably font-dependent!! float t = tm.fontSize / tm.font.fontInfo.LineHeight; float magic_k = 10.929f; // [RMS] solve-for-x given a few different fontSize values float font_size_y = magic_k * t; tm.fontSizeYScale = 1 / font_size_y; tm.SetTextSizeFromHeight(fTextHeight); //float fScaleH = fTextHeight / font_size_y; //tm.transform.localScale = new Vector3f(fScaleH, fScaleH, fScaleH); float fTextWidth = tm.GetTextScaleForHeight(fTextHeight) * size.x; textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; return(new fTextGameObject(textGO, new fText(tm, TextType.TextMeshPro), new Vector2f(fTextWidth, fTextHeight))); }
// extracts MeshFilter object from input GameObject and passes it to a custom constructor // function MakeSOFunc (if null, creates basic MeshSO). Then optionally adds to Scene, // preserving existing 3D position if desired (default true) public static SceneObject ImportExistingUnityMesh(GameObject go, FScene scene, bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true, Func <Mesh, SOMaterial, SceneObject> MakeSOFunc = null) { MeshFilter meshF = go.GetComponent <MeshFilter>(); if (meshF == null) { throw new Exception("SceneUtil.ImportExistingUnityMesh: gameObject is not a mesh!!"); } Vector3f scale = go.GetLocalScale(); // [RMS] why don't we bake transform into mesh ??! then we could handle non-uniform scaling... if (SceneTransforms.IsUniformScale(scale) == false) { throw new Exception("UnitySceneUtil.ImportExistingUnityMesh: nonuniform scaling is not supported..."); } Mesh useMesh = meshF.mesh; // makes a copy AxisAlignedBox3f bounds = useMesh.bounds; // bounds.Center is wrt local frame of input go // ie offset from origin in local coordinates // if we want to move frame to center of mesh, we have to re-center it at origin // in local coordinates if (bRecenterFrame) { UnityUtil.TranslateMesh(useMesh, -bounds.Center.x, -bounds.Center.y, -bounds.Center.z); useMesh.RecalculateBounds(); } SceneObject newSO = (MakeSOFunc != null) ? MakeSOFunc(useMesh, scene.DefaultMeshSOMaterial) : new MeshSO().Create(useMesh, scene.DefaultMeshSOMaterial); if (bAddToScene) { scene.AddSceneObject(newSO, false); } if (bKeepWorldPosition) { // compute world rotation/location. If we re-centered the mesh, we need // to offset by the transform we applied above in local coordinates // (hence we have to rotate & scale) if (go.transform.parent != null) { throw new Exception("UnitySceneUtil.ImportExistingUnityMesh: Not handling case where GO has a parent transform"); } Frame3f goFrameW = UnityUtil.GetGameObjectFrame(go, CoordSpace.WorldCoords); Vector3f originW = goFrameW.Origin; if (bRecenterFrame) { originW += goFrameW.Rotation * (scale * bounds.Center); // offset initial frame to be at center of mesh } // convert world frame and offset to scene coordinates Frame3f goFrameS = scene.ToSceneFrame(goFrameW); Vector3f boundsCenterS = scene.ToSceneP(originW); // translate new object to position in scene Frame3f curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.Origin += boundsCenterS; newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply rotation (around current origin) curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.RotateAround(curF.Origin, goFrameS.Rotation); newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply local scale newSO.SetLocalScale(scale); } return(newSO); }
public virtual void Create(FScene parentScene, List <SceneObject> targets) { this.parentScene = parentScene; this.targets = targets; root = GameObjectFactory.CreateParentGO("TransformGizmo"); var xMaterial = Factory.MakeMaterial(AxisGizmoFlags.AxisTranslateX); var xHoverMaterial = Factory.MakeHoverMaterial(AxisGizmoFlags.AxisTranslateX); var yMaterial = Factory.MakeMaterial(AxisGizmoFlags.AxisTranslateY); var yHoverMaterial = Factory.MakeHoverMaterial(AxisGizmoFlags.AxisTranslateY); var zMaterial = Factory.MakeMaterial(AxisGizmoFlags.AxisTranslateZ); var zHoverMaterial = Factory.MakeHoverMaterial(AxisGizmoFlags.AxisTranslateZ); if (Factory.Supports(AxisGizmoFlags.AxisTranslateX)) { translate_x = append_widget(AxisGizmoFlags.AxisTranslateX, 0, "x_translate", xMaterial, xHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.AxisTranslateY)) { translate_y = append_widget(AxisGizmoFlags.AxisTranslateY, 1, "y_translate", yMaterial, yHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.AxisTranslateZ)) { translate_z = append_widget(AxisGizmoFlags.AxisTranslateZ, 2, "z_translate", zMaterial, zHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.AxisRotateX)) { rotate_x = append_widget(AxisGizmoFlags.AxisRotateX, 0, "x_rotate", xMaterial, xHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.AxisRotateY)) { rotate_y = append_widget(AxisGizmoFlags.AxisRotateY, 1, "y_rotate", yMaterial, yHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.AxisRotateZ)) { rotate_z = append_widget(AxisGizmoFlags.AxisRotateZ, 2, "z_rotate", zMaterial, zHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.PlaneTranslateX)) { translate_yz = append_widget(AxisGizmoFlags.PlaneTranslateX, 0, "yz_translate", xMaterial, xHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.PlaneTranslateY)) { translate_xz = append_widget(AxisGizmoFlags.PlaneTranslateY, 1, "xz_translate", yMaterial, yHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.PlaneTranslateZ)) { translate_xy = append_widget(AxisGizmoFlags.PlaneTranslateZ, 2, "xy_translate", zMaterial, zHoverMaterial); } if (Factory.Supports(AxisGizmoFlags.UniformScale)) { uniform_scale = append_widget(AxisGizmoFlags.UniformScale, 0, "uniform_scale", null, null); } gizmoGeomBounds = UnityUtil.GetGeometryBoundingBox(root, true); gizmoGeomBounds.Contain(Vector3d.Zero); initialGizmoRadius = gizmoGeomBounds.MaxDim; foreach (var widget in Widgets) { widget.Value.SetGizmoInitialRadius(initialGizmoRadius); } // disable shadows on widget components foreach (var go in GameObjects) { MaterialUtil.DisableShadows(go); } update_active(); eCurrentFrameMode = FrameType.LocalFrame; SetActiveFrame(eCurrentFrameMode); SetLayer((GizmoLayer == -1) ? FPlatform.WidgetOverlayLayer : GizmoLayer); // seems like possibly this geometry will be shown this frame, before PreRender() // is called, which means that on next frame the geometry will pop. // So we hide here and show in PreRender root.Hide(); }
// [TODO] currently only allows for left-justified text. // Can support center/right, but the translate block needs to be rewritten // (can we generalize as target-center of 2D bbox?? public static fTextGameObject CreateTextMeshProGO( string sName, string sText, Colorf textColor, float fTextHeight, BoxPosition textOrigin = BoxPosition.Center, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshProExt tm = textGO.AddComponent <TextMeshProExt>(); //tm.isOrthographic = false; tm.alignment = TextAlignmentOptions.TopLeft; tm.enableWordWrapping = false; tm.autoSizeTextContainer = true; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); // convert TextContainerAnchor (which refers to TextContainer, that was deprecated) to // pivot point, which we will set on rectTransform Vector2f pivot = GetTextMeshProPivot(TextContainerAnchors.TopLeft); if (textOrigin == BoxPosition.Center) { pivot = GetTextMeshProPivot(TextContainerAnchors.Middle); tm.alignment = TextAlignmentOptions.Center; } else if (textOrigin == BoxPosition.BottomLeft) { pivot = GetTextMeshProPivot(TextContainerAnchors.BottomLeft); tm.alignment = TextAlignmentOptions.BottomLeft; } else if (textOrigin == BoxPosition.TopRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.TopRight); tm.alignment = TextAlignmentOptions.TopRight; } else if (textOrigin == BoxPosition.BottomRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.BottomRight); tm.alignment = TextAlignmentOptions.BottomRight; } else if (textOrigin == BoxPosition.CenterLeft) { pivot = GetTextMeshProPivot(TextContainerAnchors.Left); tm.alignment = TextAlignmentOptions.Left; } else if (textOrigin == BoxPosition.CenterRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.Right); tm.alignment = TextAlignmentOptions.Right; } else if (textOrigin == BoxPosition.CenterTop) { pivot = GetTextMeshProPivot(TextContainerAnchors.Top); tm.alignment = TextAlignmentOptions.Top; } else if (textOrigin == BoxPosition.CenterBottom) { pivot = GetTextMeshProPivot(TextContainerAnchors.Bottom); tm.alignment = TextAlignmentOptions.Bottom; } tm.rectTransform.pivot = pivot; tm.ForceMeshUpdate(); // read out bounds so we can know size (does this matter? why does fTextGO have size field?) AxisAlignedBox3f bounds = tm.bounds; Vector2f size = new Vector2f(bounds.Width, bounds.Height); tm.fontSizeYScale = GetYScale(tm); tm.SetTextSizeFromHeight(fTextHeight); float fScale = tm.GetTextScaleForHeight(fTextHeight); float fTextWidth = fScale * size.x; // set rendering queue (?) textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; fTextGameObject go = new fTextGameObject(textGO, new fText(tm, TextType.TextMeshPro), new Vector2f(fTextWidth, fTextHeight)); if (fOffsetZ != 0) { Vector3f pos = go.GetLocalPosition(); pos.z += fOffsetZ; go.SetLocalPosition(pos); } return(go); }