public SpawnTurretSystem(AABox spawnArea, int count, IRandomProvider random, EntityContext context) : base(batchSize: 100) { this.spawnArea = spawnArea; this.count = count; this.random = random; this.context = context; }
public SpawnSpaceshipSystem(AABox spawnArea, int targetCount, IRandomProvider random, EntityContext context) : base(batchSize: 100) { this.spawnArea = spawnArea; this.targetCount = targetCount; this.random = random; this.context = context; }
public static bool AABoxIntersection(AABox box1, AABox box2) { Vector3 distance = box2.myOrigin - box1.myOrigin; return(Math.Abs(distance.X) <= (box1.mySize.X + box2.mySize.X) && Math.Abs(distance.Y) <= (box1.mySize.Y + box2.mySize.Y) && Math.Abs(distance.Z) <= (box1.mySize.Z + box2.mySize.Z)); }
/// <summary> /// Calculates bounds of the visible content for this component. /// </summary> /// <param name="box">Bounds in world space represented as an axis aligned bounding box.</param> /// <param name="sphere">Bounds in world space represented as a sphere.</param> /// <returns>True if the bounds have non-zero volume, false otherwise.</returns> protected internal virtual bool CalculateBounds(out AABox box, out Sphere sphere) { Vector3 pos = SceneObject.Position; box = new AABox(pos, pos); sphere = new Sphere(pos, 0.0f); return(false); }
/// <summary> /// Focuses the camera on the currently selected object(s). /// </summary> public void FrameSelected() { SceneObject[] selectedObjects = Selection.SceneObjects; if (selectedObjects.Length > 0) { AABox box = EditorUtility.CalculateBounds(Selection.SceneObjects); FrameBounds(box); } }
public static bool AABoxMovingSphereIntersection(AABox box, Sphere s, Vector3 vel, out float t, out Vector3 hit) { //get bounding box of original box expanded by radius AABox expanded = box; expanded.myMin.X -= s.myRadius; expanded.myMin.Y -= s.myRadius; expanded.myMin.Z -= s.myRadius; expanded.myMax.X += s.myRadius; expanded.myMax.Y += s.myRadius; expanded.myMax.Z += s.myRadius; //intersect ray of sphere center along vel against expanded box t = 0.0f; if (rayAABBIntersection(s.myCenter, vel, expanded, out t, out hit) == false || t > vel.Length) { return(false); } int u = 0; int v = 0; if (hit.X < box.myMin.X) { u |= 1; } if (hit.X > box.myMax.X) { v |= 1; } if (hit.Y < box.myMin.Y) { u |= 2; } if (hit.Y > box.myMax.Y) { v |= 2; } if (hit.Z < box.myMin.Z) { u |= 4; } if (hit.Z > box.myMax.Z) { v |= 4; } int m = u + v; if (m == 7) { } if ((m & (m - 1)) == 0) { return(true); } return(false); }
public CollisionSystemGrid(int nx, int ny, int nz, float dx, float dy, float dz) { this.nx = nx; this.ny = ny; this.nz = nz; this.dx = dx; this.dy = dy; this.dz = dz; sizeX = nx * dx; sizeY = ny * dy; sizeZ = nz * dz; minDelta = System.Math.Min(System.Math.Min(dx, dy), dz); var numEntries = nx * ny * nz * 2; gridEntries = new List <GridEntry>(numEntries); gridBoxes = new List <AABox>(numEntries); tempGridLists = new List <GridEntry>(numEntries); freeGrids = new Stack <GridEntry>(numEntries); for (var i = 0; i < numEntries; ++i) { var entry = new GridEntry(); entry.GridIndex = -2; freeGrids.Push(entry); } for (var i = 0; i < nx * ny * nz; ++i) { var gridEntry = freeGrids.Pop(); gridEntry.GridIndex = i; gridEntries.Add(gridEntry); gridBoxes.Add(null); } overflowEntries = freeGrids.Pop(); overflowEntries.GridIndex = -1; for (var iX = 0; iX < nx; ++iX) { for (var iY = 0; iY < ny; ++iY) { for (var iZ = 0; iZ < nz; ++iZ) { var box = new AABox(); box.AddPoint(new Vector3(iX * dx, iY * dy, iZ + dz)); box.AddPoint(new Vector3(iX * dx + dx, iY * dy + dy, iZ * dz + dz)); var index = CalcIndex(iX, iY, iZ); gridBoxes[index] = box; } } } }
/// <inheritdoc/> protected internal override bool CalculateBounds(out AABox box, out Sphere sphere) { sphere = Bounds; Vector3 extents = new Vector3(sphere.Radius, sphere.Radius, sphere.Radius); box = new AABox(sphere.Center - extents, sphere.Center + extents); return(true); }
private static void DrawGizmo(Animation animation) { SceneObject so = animation.SceneObject; Gizmos.Color = Color.Green; Gizmos.Transform = Matrix4.TRS(so.Position, so.Rotation, Vector3.One); AABox bounds = animation.Bounds; Vector3 scaledSize = bounds.Size * so.Scale; Gizmos.DrawWireCube(bounds.Center, scaledSize * 0.5f); }
/// <summary> /// Indicates if a segment overlaps an AABox /// </summary> /// <param name="seg"></param> /// <param name="AABox"></param> /// <returns></returns> public static bool SegmentAABoxOverlap(Segment seg, AABox AABox) { Vector3 p0 = seg.Origin; Vector3 p1 = seg.GetEnd(); float[] faceOffsets = new float[2]; // The AABox faces are aligned with the world directions. Loop // over the 3 directions and do the two tests. for (int iDir = 0; iDir < 3; iDir++) { int jDir = (iDir + 1) % 3; int kDir = (iDir + 2) % 3; // one plane goes through the origin, one is offset faceOffsets[0] = JiggleUnsafe.Get(AABox.MinPos, iDir); faceOffsets[1] = JiggleUnsafe.Get(AABox.MaxPos, iDir); for (int iFace = 0; iFace < 2; iFace++) { // distance of each point from to the face plane float dist0 = JiggleUnsafe.Get(ref p0, iDir) - faceOffsets[iFace]; float dist1 = JiggleUnsafe.Get(ref p1, iDir) - faceOffsets[iFace]; float frac = -1.0f; if (dist0 * dist1 < -JiggleMath.Epsilon) frac = -dist0 / (dist1 - dist0); else if (System.Math.Abs(dist0) < JiggleMath.Epsilon) frac = 0.0f; else if (System.Math.Abs(dist1) < JiggleMath.Epsilon) frac = 1.0f; if (frac >= 0.0f) { //Assert(frac <= 1.0f); Vector3 pt = seg.GetPoint(frac); // check the point is within the face rectangle if ((JiggleUnsafe.Get(ref pt, jDir) > JiggleUnsafe.Get(AABox.MinPos, jDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, jDir) < JiggleUnsafe.Get(AABox.MaxPos, jDir) + JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) > JiggleUnsafe.Get(AABox.MinPos, kDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) < JiggleUnsafe.Get(AABox.MaxPos, kDir) + JiggleMath.Epsilon)) { return true; } } } } return false; }
public static bool pointInAABox(AABox box, Vector3 point) { if (point.X >= box.myMin.X && point.Y >= box.myMin.Y && point.Z >= box.myMin.Z && point.X < box.myMax.X && point.Y < box.myMax.Y && point.Z < box.myMax.Z) { return(true); } return(false); }
public static bool AABBContainsSphere(Vector3 sphereCenter, float radius, AABox box) { if (sphereCenter.X - radius >= box.myMin.X && sphereCenter.Y - radius >= box.myMin.Y && sphereCenter.Z - radius >= box.myMin.Z && sphereCenter.X + radius < box.myMax.X && sphereCenter.Y + radius < box.myMax.Y && sphereCenter.Z + radius < box.myMax.Z) { return(true); } return(false); }
public override bool Run(FeatureContext context) { const float len = 100.0f; const int nDim = 50; float[] pointBuffer = new float[nDim * nDim * nDim * 3]; float[] colorBuffer = new float[nDim * nDim * nDim * 3]; int idx = -1; for (int ii = 0; ii < nDim; ++ii) { for (int jj = 0; jj < nDim; ++jj) { for (int kk = 0; kk < nDim; ++kk) { ++idx; pointBuffer[idx * 3] = ii * len; pointBuffer[idx * 3 + 1] = jj * len; pointBuffer[idx * 3 + 2] = kk * len; colorBuffer[idx * 3] = ((float)ii) / ((float)nDim); colorBuffer[idx * 3 + 1] = ((float)jj) / ((float)nDim); colorBuffer[idx * 3 + 2] = ((float)kk) / ((float)nDim); } } } PointStyle pointStyle = new PointStyle(); //pointStyle.SetPointSize(4.0f); pointStyle.SetMarker("cross"); PointCloudNode pcn = new PointCloudNode(); pcn.SetPointStyle(pointStyle); pcn.SetPoints(pointBuffer); pcn.SetColors(colorBuffer); pcn.ComputeBBox(); AABox bbox = pcn.GetBBox(); Vector3 pt = bbox.MinPt; context.ShowSceneNode(pcn); return(true); }
/// <summary> /// Moves and orients a camera so that the provided bounds end covering the camera's viewport. /// </summary> /// <param name="bounds">Bounds to frame in camera's view.</param> /// <param name="padding">Amount of padding to leave on the borders of the viewport, in percent [0, 1].</param> private void FrameBounds(AABox bounds, float padding = 0.0f) { // TODO - Use AABox bounds directly instead of a sphere to be more accurate float worldWidth = bounds.Size.Length; float worldHeight = worldWidth; if (worldWidth == 0.0f) { worldWidth = 1.0f; } if (worldHeight == 0.0f) { worldHeight = 1.0f; } float boundsAspect = worldWidth / worldHeight; float paddingScale = MathEx.Clamp01(padding) + 1.0f; float frustumWidth; // If camera has wider aspect than bounds then height will be the limiting dimension if (camera.AspectRatio > boundsAspect) { frustumWidth = worldHeight * camera.AspectRatio * paddingScale; } else // Otherwise width { frustumWidth = worldWidth * paddingScale; } float distance = CalcDistanceForFrustumWidth(frustumWidth); Vector3 forward = bounds.Center - SceneObject.Position; forward.Normalize(); CameraState state = new CameraState(); state.Position = bounds.Center - forward * distance; state.Rotation = Quaternion.LookRotation(forward, Vector3.YAxis); state.Ortographic = camera.ProjectionType == ProjectionType.Orthographic; state.FrustumWidth = frustumWidth; SetState(state); }
/// <inheritoc/> protected internal override void Initialize(int layoutIndex) { GUILayoutX boundsLayout = new GUILayoutX(); centerField = new GUIVector3Field(new LocEdString("Center"), 50); sizeField = new GUIVector3Field(new LocEdString("Size"), 50); layout.AddElement(layoutIndex, boundsLayout); boundsLayout.AddElement(new GUILabel(new LocEdString(title), GUIOption.FixedWidth(100))); GUILayoutY boundsContent = boundsLayout.AddLayoutY(); boundsContent.AddElement(centerField); boundsContent.AddElement(sizeField); centerField.OnValueChanged += x => { AABox bounds = property.GetValue <AABox>(); Vector3 min = x - bounds.Size * 0.5f; Vector3 max = x + bounds.Size * 0.5f; RecordStateForUndoIfNeeded(); property.SetValue(new AABox(min, max)); state |= InspectableState.ModifyInProgress; }; centerField.OnConfirm += x => OnFieldValueConfirm(); centerField.OnFocusLost += OnFieldValueConfirm; centerField.OnFocusGained += RecordStateForUndoRequested; sizeField.OnValueChanged += x => { AABox bounds = property.GetValue <AABox>(); Vector3 min = bounds.Center - x * 0.5f; Vector3 max = bounds.Center + x * 0.5f; RecordStateForUndoIfNeeded(); property.SetValue(new AABox(min, max)); state |= InspectableState.ModifyInProgress; }; sizeField.OnConfirm += x => OnFieldValueConfirm(); sizeField.OnFocusLost += OnFieldValueConfirm; sizeField.OnFocusGained += RecordStateForUndoRequested; }
/**********************/ /* Don't Work */ /* (enough) */ /**********************/ // Triangle / Bounding Box (AABB) Intersection Test public bool IsIntersecting(AABox box, Triangle triangle) { float triangleMin, triangleMax; float boxMin, boxMax; // Test the box normals Vector3[] boxNormals = { Vector3.right, Vector3.up, Vector3.forward }; for (int i = 0; i < 3; i++) { Project(triangle.vertices, boxNormals[i], out triangleMin, out triangleMax); if (triangleMax < box.StartCoords(i) || triangleMin > box.EndCoords(i)) { return(false); } } // Test the triangle normal float triangleOffset = Vector3.Dot(triangle.normal, triangle.a); Project(box.vertices, triangle.normal, out boxMin, out boxMax); if (boxMax < triangleOffset || boxMin > triangleOffset) { return(false); } // Test the nine edge cross-products Vector3[] triangleEdges = { triangle.b - triangle.a, triangle.b - triangle.c, triangle.b - triangle.c }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { // The box normals are the same as it's edge tangents Vector3 axis = Vector3.Cross(triangleEdges[i], boxNormals[j]); Project(box.vertices, axis, out boxMin, out boxMax); Project(triangle.vertices, axis, out triangleMin, out triangleMax); if (boxMax < triangleMin || boxMin > triangleMax) { return(false); // No intersection possible } } } // No separating axis found. return(true); }
/// <inheritdoc/> public override InspectableState Refresh(int layoutIndex) { if ((centerField != null && !centerField.HasInputFocus) && (sizeField != null && !sizeField.HasInputFocus)) { AABox box = property.GetValue <AABox>(); centerField.Value = box.Center; sizeField.Value = box.Size; } InspectableState oldState = state; if (state.HasFlag(InspectableState.Modified)) { state = InspectableState.NotModified; } return(oldState); }
public Solid(TopoShape solid) { BoundingBox = solid.GetBBox(); var faces = GlobalInstance.TopoExplor.ExplorFaces(solid); TopoShapeProperty prop = new TopoShapeProperty(); List <FaceInfo> dictFaceByArea = new List <FaceInfo>(); for (int ii = 0; ii < faces.Size(); ++ii) { var face = faces.GetAt(ii); prop.SetShape(face); double area = prop.SurfaceArea(); var faceInfo = new FaceInfo(face, ii, area); dictFaceByArea.Add(faceInfo); Faces.Add(ii, faceInfo); } dictFaceByArea.Sort((a, b) => { return((int)((b.Area - a.Area) * 1000)); }); var baseFace = dictFaceByArea[0]; foreach (var item in baseFace.Edges) { EdgeGroup eg = new EdgeGroup(item.Value); EdgeGroups.Add(eg); } for (int ii = 2; ii < dictFaceByArea.Count; ++ii) { var faceInfo = dictFaceByArea[ii]; if (AddLongFace(faceInfo)) { continue; } AddSideFace(faceInfo); } }
public static bool rayAABBIntersection(Vector3 point, Vector3 dir, AABox box, out float tmin, out Vector3 hit) { tmin = 0.0f; float tmax = float.MaxValue; for (int i = 0; i < 3; i++) { if (Math.Abs(dir[i]) < float.Epsilon) { if (point[i] < box.myMin[i] || point[i] > box.myMax[i]) { hit = Vector3.Zero; return(false); } } else { float ood = 1.0f / dir[i]; float t1 = (box.myMin[i] - point[i]) * ood; float t2 = (box.myMax[i] - point[i]) * ood; if (t1 > t2) { float temp = t2; t2 = t1; t1 = temp; } tmin = Math.Max(tmin, t1); tmax = Math.Min(tmax, t2); if (tmin > tmax) { hit = Vector3.Zero; return(false); } } } hit = point + dir * tmin; return(true); }
public static Vector3 closestPointOn(AABox xBox, Vector3 Point) { Vector3 q = Vector3.Zero; for (int i = 0; i < 3; i++) { float v = Point[i]; if (v < xBox.myMin[i]) { v = xBox.myMin[i]; } if (v > xBox.myMax[i]) { v = xBox.myMax[i]; } q[i] = v; } return(q); }
public Window CreateMainMenu() { Texture2D buttonSheet = ScreenManager.Content.Load <Texture2D>(".//Old Content//UI//Buttons.png"); AABox buttonBox = new AABox(new Rectangle(0, 0, 87, 23)); FlatColorElement spacer1 = new FlatColorElement(new Color(255, 255, 255, 0), "Spacer 1"); ButtonElement newGame = new ButtonElement(new Button(new AABox(buttonBox), buttonSheet, new Rectangle[] { new Rectangle(406, 0, 87, 23), new Rectangle(406, 0, 87, 23), new Rectangle(406, 23, 87, 23), new Rectangle(406, 0, 87, 23) }, new Coordinate(0, 0)), new Coordinate(87, 23), "New Game", SideTack.Center); newGame.Clicked += onClickNewGame; ButtonElement intro = new ButtonElement(new Button(new AABox(buttonBox), buttonSheet, new Rectangle[] { new Rectangle(406, 46, 87, 23), new Rectangle(406, 46, 87, 23), new Rectangle(406, 69, 87, 23), new Rectangle(406, 46, 87, 23) }, new Coordinate(0, 0)), new Coordinate(87, 23), "Introduction", SideTack.Center); intro.Clicked += onClickIntroduction; ButtonElement loadGame = new ButtonElement(new Button(new AABox(buttonBox), buttonSheet, new Rectangle[] { new Rectangle(406, 92, 87, 23), new Rectangle(406, 92, 87, 23), new Rectangle(406, 115, 87, 23), new Rectangle(406, 92, 87, 23) }, new Coordinate(0, 0)), new Coordinate(87, 23), "Load Game", SideTack.Center); loadGame.Clicked += onClickLoadGame; ButtonElement prefs = new ButtonElement(new Button(new AABox(buttonBox), buttonSheet, new Rectangle[] { new Rectangle(406, 138, 87, 23), new Rectangle(406, 138, 87, 23), new Rectangle(406, 161, 87, 23), new Rectangle(406, 138, 87, 23) }, new Coordinate(0, 0)), new Coordinate(87, 23), "Preferences", SideTack.Center); prefs.Clicked += onClickPreferences; ButtonElement exit = new ButtonElement(new Button(new AABox(buttonBox), buttonSheet, new Rectangle[] { new Rectangle(406, 184, 87, 23), new Rectangle(406, 184, 87, 23), new Rectangle(406, 207, 87, 23), new Rectangle(406, 184, 87, 23) }, new Coordinate(0, 0)), new Coordinate(87, 23), "Exit", SideTack.Center); exit.Clicked += onClickExit; TextElement version = new TextElement("Version 0.01", "MSSansSerif", TempGlobals.BorderColors[1], "Version", ResizeKind.FillRatio); TextElement copyright = new TextElement("Copyright let's say Sierra, sure", "MSSansSerif", TempGlobals.BorderColors[1], "Copyright", ResizeKind.FillRatio); TextElement arr = new TextElement("Please Don't Sue", "MSSansSerif", TempGlobals.BorderColors[1], "ARR", ResizeKind.FillRatio); SpaceFillList mainCont = new SpaceFillList(new float[] { 0.2f, 1, 1, 1, 1, 1, 0.5f, 0.5f, 0.5f }, new Element[] { spacer1, newGame, intro, loadGame, prefs, exit, version, copyright, arr }, false, "TopCont"); Rectangle dimensions = new Rectangle((ScreenManager.StaticGame.Window.ClientBounds.Width - 293) / 2, (ScreenManager.StaticGame.Window.ClientBounds.Height - 244) / 2, 293, 244); Window mainMenuWindow = new Window(windows, ScreenManager.Content, dimensions, TempGlobals.BorderColors, mainCont, "Program Control", false); return(mainMenuWindow); }
public override bool Run(FeatureContext context) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "STL (*.stl)|*.stl|IGES (*.igs;*.iges)|*.igs;*.iges|STEP (*.stp;*.step)|*.stp;*.step|BREP (*.brep)|*.brep|All Files(*.*)|*.*"; if (DialogResult.OK != dlg.ShowDialog()) { return(false); } context.RenderView.RenderTimer.Enabled = false; TopoShape shape = GlobalInstance.BrepTools.LoadFile(new AnyCAD.Platform.Path(dlg.FileName)); context.RenderView.RenderTimer.Enabled = true; MessageBox.Show("loaded"); if (shape != null) { //context.ShowGeometry(shape, new ElementId(100)); //GlobalInstance.BrepTools.SaveFile(shape, new Path(dlg.FileName + ".brep")); AABox bbox = shape.GetBBox(); Vector3 size = bbox.Size(); Vector3 start = new Vector3(bbox.MinPt.X - 10, bbox.MinPt.Y + size.Y * 0.5f, bbox.MinPt.Z - 10); TopoShape boxShape = GlobalInstance.BrepTools.MakeBox(start, Vector3.UNIT_Z, new Vector3(size.X + 20, size.Y * 0.25f, size.Z + 20)); shape = GlobalInstance.BrepTools.BooleanCut(shape, boxShape); MessageBox.Show("cut!"); var groups = GlobalInstance.TopoExplor.ExplorSubShapes(shape); for (int ii = 0, len = groups.Size(); ii < len; ++ii) { shape = groups.GetAt(ii); var node = context.ShowGeometry(shape, new ElementId(100)); var fs = new FaceStyle(); fs.SetColor(ii * 100, 0, ii + 200); node.SetFaceStyle(fs); } } return(true); }
public static bool AABoxSweepIntersection(AABox box1, Vector3 b1Vel, AABox box2, Vector3 b2Vel, out float t) { Vector3 v = b2Vel - b1Vel; //relative velocity of box 2 to box 1 Vector3 u0 = Vector3.Zero; Vector3 u1 = Vector3.One; if (AABoxIntersection(box1, box2) == true) { u0 = u1 = Vector3.Zero; t = 0; return(true); } for (int i = 0; i < 3; i++) { if (box1.myMax[i] < box2.myMin[i] && v[i] < 0) { u0[i] = (box1.myMax[i] - box2.myMin[i]) / v[i]; } else if (box2.myMax[i] < box1.myMin[i] && v[i] > 0) { u0[i] = (box1.myMin[i] - box2.myMax[i]) / v[i]; } if (box2.myMax[i] > box1.myMin[i] && v[i] < 0) { u1[i] = (box1.myMin[i] - box2.myMax[i]) / v[i]; } else if (box1.myMax[i] > box2.myMin[i] && v[i] > 0) { u1[i] = (box1.myMax[i] - box2.myMin[i]) / v[i]; } } float t0 = Math.Max(u0.X, Math.Max(u0.Y, u0.Z)); float t1 = Math.Min(u1.X, Math.Min(u1.Y, u1.Z)); t = t0; return(t0 <= t1); }
public static bool AABoxSphereIntersection(AABox box1, Vector3 spherePos, float sphereRadius) { float s = 0; float d = 0; float sphereRadiusSquared = sphereRadius * sphereRadius; for (int i = 0; i < 3; i++) { if (spherePos[i] < box1.myMin[i]) { s = spherePos[i] = box1.myMin[i]; d += s * s; } else if (spherePos[i] > box1.myMax[i]) { s = spherePos[i] - box1.myMax[i]; d += s * s; } } return(d <= sphereRadiusSquared); }
/// <inheritdoc/> protected internal override InspectableState Refresh(bool force = false) { LightProbeVolume lpv = InspectedObject as LightProbeVolume; if (lpv == null) { return(InspectableState.NotModified); } InspectableState oldState = modifyState; if (modifyState.HasFlag(InspectableState.Modified)) { modifyState = InspectableState.NotModified; } AABox gridVolume = lpv.GridVolume; Vector3 size = gridVolume.Maximum - gridVolume.Minimum; Vector3 position = gridVolume.Minimum + size * 0.5f; if (!positionField.HasInputFocus || force) { positionField.Value = position; } if (!sizeField.HasInputFocus || force) { sizeField.Value = size; } if (!densityField.HasInputFocus || force) { Vector3I cellCount = lpv.CellCount; densityField.Value = new Vector3(cellCount.x, cellCount.y, cellCount.z); } return(oldState); }
public static bool AABoxSphereIntersection(AABox box, Vector3 sphereCenter, float radius, out Vector3 hitNormal, out float hitDepth) { if (AABBContainsSphere(sphereCenter, radius, box)) { // Do special code. // here, for now don't do a collision, until the center is // outside the box hitDepth = 0.0f; hitNormal = Vector3.Zero; return(true); } // get closest point on box from sphere center Vector3 closest = Distance.closestPointOn(box, sphereCenter); // find the separation Vector3 diff = sphereCenter - closest; // check if points are far enough float dist = diff.Length; if (dist > radius) { hitDepth = 0.0f; hitNormal = Vector3.Zero; return(false); } // collision depth hitDepth = radius - dist; // normal of collision (going towards the sphere center) hitNormal = diff / dist; return(true); }
private static void DrawGizmo(Animation animation) { SceneObject so = animation.SceneObject; Gizmos.Color = Color.Green; Gizmos.Transform = Matrix4.Identity; Matrix4 parentTfrm; if (so.Parent != null) { parentTfrm = so.Parent.WorldTransform; } else { parentTfrm = Matrix4.Identity; } AABox bounds = animation.Bounds; bounds.TransformAffine(parentTfrm); Gizmos.DrawWireCube(bounds.Center, bounds.Size * 0.5f); }
/// <summary> /// Creates new bounds. /// </summary> /// <param name="box">Axis aligned box representation of the bounds.</param> /// <param name="sphere">Sphere representation of the bounds.</param> public Bounds(AABox box, Sphere sphere) { Box = box; Sphere = sphere; }
public void CopyPasteContextWithBlock() { var initContextDesc = VFXLibrary.GetContexts().Where(t => t.name == "Initialize").First(); var newContext = m_ViewController.AddVFXContext(new Vector2(100, 100), initContextDesc); m_ViewController.ApplyChanges(); Assert.AreEqual(m_ViewController.allChildren.Where(t => t is VFXContextController).Count(), 1); var contextController = m_ViewController.allChildren.OfType <VFXContextController>().First(); Assert.AreEqual(contextController.model, newContext); var flipBookBlockDesc = VFXLibrary.GetBlocks().First(t => t.name == "Set Tex Index "); contextController.AddBlock(0, flipBookBlockDesc.CreateInstance()); m_ViewController.ApplyChanges(); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); VFXView view = window.graphView; view.controller = m_ViewController; view.ClearSelection(); foreach (var element in view.Query().OfType <GraphElement>().ToList().OfType <ISelectable>()) { view.AddToSelection(element); } VFXSlot boundsSlot = newContext.GetInputSlot(0); AABox originalBounds = new AABox() { center = Vector3.one, size = Vector3.one * 10 }; boundsSlot.value = originalBounds; VFXBlock flipBookBlock = m_ViewController.contexts.First().blockControllers.First().model; VFXSlot minValueSlot = flipBookBlock.GetInputSlot(0); float originalMinValue = 123.456f; minValueSlot.value = originalMinValue; view.CopySelectionCallback(); boundsSlot.value = new AABox() { center = Vector3.zero, size = Vector3.zero }; minValueSlot.value = 789f; view.PasteCallback(); var elements = view.Query().OfType <GraphElement>().ToList(); var contexts = elements.OfType <VFXContextUI>().ToArray(); var copyContext = elements.OfType <VFXContextUI>().Select(t => t.controller).First(t => t.model != newContext).model; var copyBoundsSlot = copyContext.GetInputSlot(0); var copyMinSlot = copyContext[0].GetInputSlot(0); Assert.AreEqual((AABox)copyBoundsSlot.value, originalBounds); Assert.AreEqual((float)copyMinSlot.value, originalMinValue); Assert.AreNotEqual(copyContext.position, newContext.position); view.PasteCallback(); elements = view.Query().OfType <GraphElement>().ToList(); contexts = elements.OfType <VFXContextUI>().ToArray(); var copy2Context = contexts.First(t => t.controller.model != newContext && t.controller.model != copyContext).controller.model; Assert.AreNotEqual(copy2Context.position, newContext.position); Assert.AreNotEqual(copy2Context.position, copyContext.position); }
public List <SerializableEntityTable> ComputeEntityTables(Dictionary <string, int> stringLookup) { // Create the new Entity tables var tableList = new List <SerializableEntityTable>(); // Create the geometry table { var tb = GetTableBuilderOrCreate(TableNames.Geometry); tb.Clear(); // We have to force evaluation because as an enumerable the bounding box could be evaluated 6 times more tb.AddField(Geometries.Select(g => AABox.Create(g.Vertices)).ToArray(), "Box"); tb.AddField(Geometries.Select(g => g.Vertices.Count), "VertexCount"); tb.AddField(Geometries.Select(g => g.Indices.Count / 3), "FaceCount"); } // TODO: add bounding box information to the nodes foreach (var tb in Tables.Values) { var table = new SerializableEntityTable { // Set the table name Name = tb.Name, // Convert the columns to named buffers IndexColumns = tb.IndexColumns .Select(kv => kv.Value.ToNamedBuffer(kv.Key)) .ToList(), NumericColumns = tb.NumericColumns .Select(kv => kv.Value.ToNamedBuffer(kv.Key)) .ToList(), StringColumns = tb.StringColumns .Select(kv => kv.Value .Select(s => stringLookup[s ?? string.Empty]) .ToArray() .ToNamedBuffer(kv.Key)) .ToList() }; // Assure that all columns are the same length var nRows = -1; foreach (var c in table.IndexColumns) { var n = c.NumElements(); if (nRows < 0) { nRows = n; } else if (nRows != n) { throw new Exception($"Invalid number of rows {n} expected {nRows}"); } } foreach (var c in table.NumericColumns) { var n = c.NumElements(); if (nRows < 0) { nRows = n; } else if (nRows != n) { throw new Exception($"Invalid number of rows {n} expected {nRows}"); } } foreach (var c in table.StringColumns) { var n = c.NumElements(); if (nRows < 0) { nRows = n; } else if (nRows != n) { throw new Exception($"Invalid number of rows {n} expected {nRows}"); } } // Properties table.Properties = tb.Properties.Select(p => new SerializableProperty { EntityIndex = p.EntityId, Name = stringLookup[p.Name], Value = stringLookup[p.Value] }).ToArray(); tableList.Add(table); } return(tableList); }
private void OnEditorUpdate() { UpdateLoadingProgress(); if (HasFocus) { if (!Input.IsPointerButtonHeld(PointerButton.Right)) { if (VirtualInput.IsButtonDown(EditorApplication.DuplicateKey)) { DuplicateSelection(); } else if (VirtualInput.IsButtonDown(EditorApplication.DeleteKey)) { DeleteSelection(); } else if (VirtualInput.IsButtonDown(viewToolKey)) { EditorApplication.ActiveSceneTool = SceneViewTool.View; } else if (VirtualInput.IsButtonDown(moveToolKey)) { EditorApplication.ActiveSceneTool = SceneViewTool.Move; } else if (VirtualInput.IsButtonDown(rotateToolKey)) { EditorApplication.ActiveSceneTool = SceneViewTool.Rotate; } else if (VirtualInput.IsButtonDown(scaleToolKey)) { EditorApplication.ActiveSceneTool = SceneViewTool.Scale; } } } // Refresh GUI buttons if needed (in case someones changes the values from script) if (editorSettingsHash != EditorSettings.Hash) { UpdateButtonStates(); editorSettingsHash = EditorSettings.Hash; } // Update scene view handles and selection sceneGrid.Draw(); bool handleActive = sceneHandles.IsActive() || sceneAxesGUI.IsActive(); Vector2I scenePos; bool inBounds = ScreenToScenePos(Input.PointerPosition, out scenePos); bool clearSelection = false; if (AllowViewportInput) { if (Input.IsPointerButtonUp(PointerButton.Left)) { clearSelection = true; } else if (Input.IsPointerButtonDown(PointerButton.Left)) { mouseDownPosition = scenePos; } } else { clearSelection = true; inBounds = false; } bool dragResult = false; if (clearSelection) { dragResult = EndDragSelection(); if (sceneHandles.IsActive()) { sceneHandles.ClearSelection(); } if (sceneAxesGUI.IsActive()) { sceneAxesGUI.ClearSelection(); } } bool draggedOver = DragDrop.DragInProgress || DragDrop.DropInProgress; draggedOver &= IsPointerHovering && inBounds && DragDrop.Type == DragDropType.Resource; if (draggedOver) { if (DragDrop.DropInProgress) { dragActive = false; if (draggedSO != null) { Selection.SceneObject = draggedSO; EditorApplication.SetSceneDirty(); } draggedSO = null; } else { if (!dragActive) { dragActive = true; ResourceDragDropData dragData = (ResourceDragDropData)DragDrop.Data; string[] draggedPaths = dragData.Paths; for (int i = 0; i < draggedPaths.Length; i++) { ResourceMeta meta = ProjectLibrary.GetMeta(draggedPaths[i]); if (meta != null) { if (meta.ResType == ResourceType.Mesh) { if (!string.IsNullOrEmpty(draggedPaths[i])) { string meshName = Path.GetFileNameWithoutExtension(draggedPaths[i]); draggedSO = UndoRedo.CreateSO(meshName, "Created a new Renderable \"" + meshName + "\""); Mesh mesh = ProjectLibrary.Load <Mesh>(draggedPaths[i]); Renderable renderable = draggedSO.AddComponent <Renderable>(); renderable.Mesh = mesh; if (mesh != null) { draggedSOOffset = mesh.Bounds.Box.Center; } else { draggedSOOffset = Vector3.Zero; } } break; } else if (meta.ResType == ResourceType.Prefab) { if (!string.IsNullOrEmpty(draggedPaths[i])) { Prefab prefab = ProjectLibrary.Load <Prefab>(draggedPaths[i]); draggedSO = UndoRedo.Instantiate(prefab, "Instantiating " + prefab.Name); if (draggedSO != null) { AABox draggedObjBounds = EditorUtility.CalculateBounds(draggedSO); draggedSOOffset = draggedObjBounds.Center; } else { draggedSOOffset = Vector3.Zero; } } break; } } } } if (draggedSO != null) { if (Input.IsButtonHeld(ButtonCode.Space)) { SnapData snapData; sceneSelection.Snap(scenePos, out snapData, new SceneObject[] { draggedSO }); Quaternion q = Quaternion.FromToRotation(Vector3.YAxis, snapData.normal); draggedSO.Position = snapData.position; draggedSO.Rotation = q; } else { Ray worldRay = camera.ScreenPointToRay(scenePos); draggedSO.Position = worldRay * DefaultPlacementDepth - draggedSOOffset; } } } return; } else { if (dragActive) { dragActive = false; if (draggedSO != null) { draggedSO.Destroy(); draggedSO = null; } } } if ((HasContentFocus || IsPointerHovering) && AllowViewportInput) { cameraController.EnableInput(true); if (inBounds && HasContentFocus) { if (Input.IsPointerButtonDown(PointerButton.Left)) { Rect2I sceneAxesGUIBounds = new Rect2I(Width - HandleAxesGUISize - HandleAxesGUIPaddingX, HandleAxesGUIPaddingY, HandleAxesGUISize, HandleAxesGUISize); if (sceneAxesGUIBounds.Contains(scenePos)) { sceneAxesGUI.TrySelect(scenePos); } else { sceneHandles.TrySelect(scenePos); } } else if (Input.IsPointerButtonHeld(PointerButton.Left) && !handleActive && !dragActive && draggedSO == null && scenePos != mouseDownPosition) { if (isDraggingSelection) { UpdateDragSelection(scenePos); } else { StartDragSelection(scenePos); } } else if (Input.IsPointerButtonUp(PointerButton.Left)) { if (!handleActive && !dragActive && !dragResult) { bool ctrlHeld = Input.IsButtonHeld(ButtonCode.LeftControl) || Input.IsButtonHeld(ButtonCode.RightControl); sceneSelection.PickObject(scenePos, ctrlHeld, new SceneObject[] { draggedSO }); } } } } else { cameraController.EnableInput(false); } if (AllowViewportInput) { SceneHandles.BeginInput(); sceneHandles.UpdateInput(scenePos, Input.PointerDelta); sceneAxesGUI.UpdateInput(scenePos); SceneHandles.EndInput(); } sceneHandles.Draw(); sceneAxesGUI.Draw(); // Must be done after handle input is processed, in order to reflect most recent transform sceneGizmos.Draw(); sceneSelection.Draw(); UpdateGridMode(); if (VirtualInput.IsButtonDown(frameKey)) { cameraController.FrameSelected(); } }
/// <summary> /// Initializes a new CollisionSystem which uses a grid to speed up collision detection. /// Use this system for larger scenes with many objects. /// </summary> /// <param name="nx">Number of GridEntries in X Direction.</param> /// <param name="ny">Number of GridEntries in Y Direction.</param> /// <param name="nz">Number of GridEntries in Z Direction.</param> /// <param name="dx">Size of a single GridEntry in X Direction.</param> /// <param name="dy">Size of a single GridEntry in Y Direction.</param> /// <param name="dz">Size of a single GridEntry in Z Direction.</param> public CollisionSystemGrid(int nx, int ny, int nz, float dx, float dy, float dz) { this.nx = nx; this.ny = ny; this.nz = nz; this.dx = dx; this.dy = dy; this.dz = dz; this.sizeX = nx * dx; this.sizeY = ny * dy; this.sizeZ = nz * dz; this.minDelta = System.Math.Min(System.Math.Min(dx, dy), dz); int numEntries = nx * ny * nz * 2; // we allocate twice as many as need for collision skins gridEntries = new List<GridEntry>(numEntries); gridBoxes = new List<AABox>(numEntries); tempGridLists = new List<GridEntry>(numEntries); freeGrids = new Stack<GridEntry>(numEntries); for (int i = 0; i < numEntries; ++i) { GridEntry entry = new GridEntry(); entry.GridIndex = -2; freeGrids.Push(entry); } for (int i = 0; i < (nx * ny * nz); ++i) { GridEntry gridEntry = freeGrids.Pop(); gridEntry.GridIndex = i; gridEntries.Add(gridEntry); gridBoxes.Add(null); } overflowEntries = freeGrids.Pop(); overflowEntries.GridIndex = -1; for (int iX = 0; iX < nx; ++iX) { for (int iY = 0; iY < ny; ++iY) { for (int iZ = 0; iZ < nz; ++iZ) { AABox box = new AABox(); box.AddPoint(new Vector3(iX * dx, iY * dy, iZ + dz)); box.AddPoint(new Vector3(iX * dx + dx, iY * dy + dy, iZ * dz + dz)); int index = CalcIndex(iX, iY, iZ); gridBoxes[index] = box; } } } }
public void Clear( bool NOTUSED ) { positions = null; triBoxes = null; tris = null; nodes = null; boundingBox = null; }
/// <summary> /// constructor clears everything /// </summary> /// <param name="aabb"></param> public Cell(AABox aabb) { mAABox = aabb; mTriangleIndices = new List<int>(); mChildCellIndices = new int[NumChildren]; Clear(); }
public void BuildOctree( int _maxTrisPerCellNOTUSED, float _minCellSizeNOTUSED) { // create tri and tri bounding box arrays triBoxes = new BoundingBox[tris.Length]; // create an infinite size root box rootNodeBox = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { triBoxes[i].Minimum = Vector3.Minimize(positions[tris[i].I0], Vector3.Minimize(positions[tris[i].I1], positions[tris[i].I2])); triBoxes[i].Maximum = Vector3.Maximize(positions[tris[i].I0], Vector3.Maximize(positions[tris[i].I1], positions[tris[i].I2])); // get size of the root box rootNodeBox.Minimum = Vector3.Minimize(rootNodeBox.Minimum, triBoxes[i].Minimum); rootNodeBox.Maximum = Vector3.Maximize(rootNodeBox.Maximum, triBoxes[i].Maximum); } boundingBox = new AABox(rootNodeBox.Minimum, rootNodeBox.Maximum); List<BuildNode> buildNodes = new List<BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; BoundingBox[] children = new BoundingBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; BoundingBox box = rootNodeBox; while (SlimDX.BoundingBox.Contains(box, triBoxes[triNum]) == ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { children[i] = CreateAABox(box, (EChild)i); if (SlimDX.BoundingBox.Contains(children[i], triBoxes[triNum]) == ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } Debug.Assert(buildNodes.Count < 0xFFFF); // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes = null; }
public override void GetBoundingBox(out AABox box) { box = octree.BoundingBox.Clone() as AABox; box.Transform = Transform; }
/// <summary> /// Tests weather two oriented boxes overlap. /// Mainly does simple SAT test (3+3 normal axes + 3x3 edge cross products) /// </summary> /// <param name="_A">First box</param> /// <param name="_B">Second box</param> /// <param name="_mB2A">Transformation from B to A</param> /// <param name="_overlapTolerance">Tolerance of this test. (essentialy both boxes are deflated with this value)</param> /// <seealso cref="BoxOverlapTest"/> /// <returns>true if there is an overlap</returns> private static bool BoxOverlapTest(AABox _A, AABox _B, Matrix _mB2A, double _overlapTolerance) { double t, t2; var tolerance = new Vector3((float) _overlapTolerance, (float) _overlapTolerance, (float) _overlapTolerance); Vector3 cB = _B.Center; Vector3 eB = 0.5f*(_B.Size - tolerance); Vector3 cA = _A.Center; Vector3 eA = 0.5f*(_A.Size - tolerance); Matrix mAR = Absolute(_mB2A); // Class I : A's basis vectors //Tx = (_mB2A.M33 * (cB.x - cA.x) + _mB2A.M34 * (cB.y - cA.y) + _mB2A.M24 * (cB.z -cA.z)) + _mB2A.M14; double Tx = (_mB2A.M33*cB.X + _mB2A.M34*cB.Y + _mB2A.M24*cB.Z) + _mB2A.M14 - cA.X; //t = r_a + r_b; t = eA.X + eB.X*mAR.M33 + eB.Y*mAR.M34 + eB.Z*mAR.M24; if (Greater(Tx, t)) return false; double Ty = (_mB2A.M21*cB.X + _mB2A.M33*cB.Y + _mB2A.M34*cB.Z) + _mB2A.M24 - cA.Y; t = eA.Y + eB.X*mAR.M21 + eB.Y*mAR.M33 + eB.Z*mAR.M34; if (Greater(Ty, t)) return false; double Tz = (_mB2A.M31*cB.X + _mB2A.M32*cB.Y + _mB2A.M33*cB.Z) + _mB2A.M34 - cA.Z; t = eA.Z + eB.X*mAR.M31 + eB.Y*mAR.M32 + eB.Z*mAR.M33; if (Greater(Tz, t)) return false; // Class II : B's basis vectors t = Tx*_mB2A.M33 + Ty*_mB2A.M21 + Tz*_mB2A.M31; t2 = eA.X*mAR.M33 + eA.Y*mAR.M21 + eA.Z*mAR.M31 + eB.X; if (Greater(t, t2)) return false; t = Tx*_mB2A.M34 + Ty*_mB2A.M33 + Tz*_mB2A.M32; t2 = eA.X*mAR.M34 + eA.Y*mAR.M33 + eA.Z*mAR.M32 + eB.Y; if (Greater(t, t2)) return false; t = Tx*_mB2A.M24 + Ty*_mB2A.M34 + Tz*_mB2A.M33; t2 = eA.X*mAR.M24 + eA.Y*mAR.M34 + eA.Z*mAR.M33 + eB.Z; if (Greater(t, t2)) return false; // Class III : 9 cross products { t = Tz*_mB2A.M21 - Ty*_mB2A.M31; t2 = eA.Y*mAR.M31 + eA.Z*mAR.M21 + eB.Y*mAR.M24 + eB.Z*mAR.M34; if (Greater(t, t2)) return false; // L = A0 x B0 t = Tz*_mB2A.M33 - Ty*_mB2A.M32; t2 = eA.Y*mAR.M32 + eA.Z*mAR.M33 + eB.X*mAR.M24 + eB.Z*mAR.M33; if (Greater(t, t2)) return false; // L = A0 x B1 t = Tz*_mB2A.M34 - Ty*_mB2A.M33; t2 = eA.Y*mAR.M33 + eA.Z*mAR.M34 + eB.X*mAR.M34 + eB.Y*mAR.M33; if (Greater(t, t2)) return false; // L = A0 x B2 t = Tx*_mB2A.M31 - Tz*_mB2A.M33; t2 = eA.X*mAR.M31 + eA.Z*mAR.M33 + eB.Y*mAR.M34 + eB.Z*mAR.M33; if (Greater(t, t2)) return false; // L = A1 x B0 t = Tx*_mB2A.M32 - Tz*_mB2A.M34; t2 = eA.X*mAR.M32 + eA.Z*mAR.M34 + eB.X*mAR.M34 + eB.Z*mAR.M21; if (Greater(t, t2)) return false; // L = A1 x B1 t = Tx*_mB2A.M33 - Tz*_mB2A.M24; t2 = eA.X*mAR.M33 + eA.Z*mAR.M24 + eB.X*mAR.M33 + eB.Y*mAR.M21; if (Greater(t, t2)) return false; // L = A1 x B2 t = Ty*_mB2A.M33 - Tx*_mB2A.M21; t2 = eA.X*mAR.M21 + eA.Y*mAR.M33 + eB.Y*mAR.M33 + eB.Z*mAR.M32; if (Greater(t, t2)) return false; // L = A2 x B0 t = Ty*_mB2A.M34 - Tx*_mB2A.M33; t2 = eA.X*mAR.M33 + eA.Y*mAR.M34 + eB.X*mAR.M33 + eB.Z*mAR.M31; if (Greater(t, t2)) return false; // L = A2 x B1 t = Ty*_mB2A.M24 - Tx*_mB2A.M34; t2 = eA.X*mAR.M34 + eA.Y*mAR.M24 + eB.X*mAR.M32 + eB.Y*mAR.M31; if (Greater(t, t2)) return false; // L = A2 x B2 } return true; }
/// <summary> /// Returns a bounding box that covers this primitive. Default returns a huge box, so /// implement this in the derived class for efficiency /// </summary> /// <returns></returns> public virtual void GetBoundingBox(out AABox box) { box = AABox.HugeBox; }
/// <inheritdoc/> protected internal override bool CalculateBounds(out AABox box, out Sphere sphere) { sphere = Bounds; Vector3 extents = new Vector3(sphere.Radius, sphere.Radius, sphere.Radius); box = new AABox(sphere.Center - extents, sphere.Center + extents); return true; }