예제 #1
0
    private static Bounds ComputeAABB(OrientedBoundingBox obb)
    {
        Vector3[] points = new Vector3[8];
        Vector3   center = obb.Center; // already in world coordinates

        points[0] = center + obb.Rotation * new Vector3(obb.Extents.x, obb.Extents.y, obb.Extents.z);
        points[1] = center + obb.Rotation * new Vector3(obb.Extents.x, obb.Extents.y, -obb.Extents.z);
        points[2] = center + obb.Rotation * new Vector3(obb.Extents.x, -obb.Extents.y, obb.Extents.z);
        points[3] = center + obb.Rotation * new Vector3(obb.Extents.x, -obb.Extents.y, -obb.Extents.z);
        points[4] = center + obb.Rotation * new Vector3(-obb.Extents.x, obb.Extents.y, obb.Extents.z);
        points[5] = center + obb.Rotation * new Vector3(-obb.Extents.x, obb.Extents.y, -obb.Extents.z);
        points[6] = center + obb.Rotation * new Vector3(-obb.Extents.x, -obb.Extents.y, obb.Extents.z);
        points[7] = center + obb.Rotation * new Vector3(-obb.Extents.x, -obb.Extents.y, -obb.Extents.z);
        float minX = float.PositiveInfinity;
        float minY = float.PositiveInfinity;
        float minZ = float.PositiveInfinity;
        float maxX = float.NegativeInfinity;
        float maxY = float.NegativeInfinity;
        float maxZ = float.NegativeInfinity;

        foreach (Vector3 point in points)
        {
            minX = Mathf.Min(minX, point.x);
            maxX = Mathf.Max(maxX, point.x);
            minY = Mathf.Min(minY, point.y);
            maxY = Mathf.Max(maxY, point.y);
            minZ = Mathf.Min(minZ, point.z);
            maxZ = Mathf.Max(maxZ, point.z);
        }
        return(new Bounds(center, new Vector3(maxX - minX, maxY - minY, maxZ - minZ)));
    }
예제 #2
0
    public static OrientedBoundingBox CameraFrameToScreenSpaceCoordinates(OrientedBoundingBox cameraFrameObb, Rect bgTextureViewPortRect, bool isTextureMirrored, CameraDevice.VideoModeData videoModeData)
    {
        bool  flag = false;
        float num  = 0f;

        switch (ScreenOrientation)
        {
        case UnityEngine.ScreenOrientation.Portrait:
            num += 90f;
            flag = true;
            break;

        case UnityEngine.ScreenOrientation.PortraitUpsideDown:
            num += 270f;
            flag = true;
            break;

        case UnityEngine.ScreenOrientation.LandscapeRight:
            num += 180f;
            break;
        }
        float   num2        = bgTextureViewPortRect.width / (flag ? ((float)videoModeData.height) : ((float)videoModeData.width));
        float   num3        = bgTextureViewPortRect.height / (flag ? ((float)videoModeData.width) : ((float)videoModeData.height));
        Vector2 center      = CameraFrameToScreenSpaceCoordinates(cameraFrameObb.Center, bgTextureViewPortRect, isTextureMirrored, videoModeData);
        Vector2 halfExtents = new Vector2(cameraFrameObb.HalfExtents.x * num2, cameraFrameObb.HalfExtents.y * num3);
        float   rotation    = cameraFrameObb.Rotation;

        if (isTextureMirrored)
        {
            rotation = -rotation;
        }
        return(new OrientedBoundingBox(center, halfExtents, ((rotation * 180f) / 3.141593f) + num));
    }
예제 #3
0
 private static Vector3 TransformWorldToOBB(Vector3 point, OrientedBoundingBox obb)
 {
     // OBB is in world units (no scale applied) but with an arbitrary center
     // point and rotation. This function converts from absolute world space to
     // OBB-local space.
     return(Quaternion.Inverse(obb.Rotation) * (point - obb.Center));
 }
    public void Embed(GameObject embedded, OrientedBoundingBox obb, Vector3 position, System.Action OnComplete = null, bool tempHighPriorityRender = true)
    {
        // Temporarily make the embedded object render in front of spatial mesh
        if (tempHighPriorityRender)
        {
            MakeHighPriorityRenderOrder(embedded);
        }

        // Compute the front (pivot point of embedded object flush with surface)
        // and back planes of the object to be embedded
        Vector3 centerPointOnFrontPlane;
        Vector3 centerPointOnBackPlane;

        ComputeDepthBounds(out centerPointOnFrontPlane, out centerPointOnBackPlane, obb, position);

        // Deform the spatial mesh to create a margin volume large enough for the
        // embedded object
        m_requestQueue.Enqueue(new EmbedRequest(obb, centerPointOnFrontPlane, centerPointOnBackPlane, embedded, OnComplete, tempHighPriorityRender));
        if (!m_working)
        {
            m_working = true;
            StartCoroutine(DeformSurfaceCoroutine());
        }

        DebugVisualization(obb);
    }
예제 #5
0
        private bool IntersectsChildContent(CanvasRootControl child, ref Ray ray, out Vector2 childSpaceLocation)
        {
            // Inline bounds calculations (it will reuse world matrix)
            OrientedBoundingBox bounds = new OrientedBoundingBox();

            bounds.Extents = new Vector3(child.Size * 0.5f, Mathf.Epsilon);
            Matrix world;

            child.Canvas.GetWorldMatrix(out world);
            Matrix offset;

            Matrix.Translation(bounds.Extents.X, bounds.Extents.Y, 0, out offset);
            Matrix.Multiply(ref offset, ref world, out bounds.Transformation);

            // Hit test
            Vector3 hitPoint;

            if (bounds.Intersects(ref ray, out hitPoint))
            {
                // Transform world-space hit point to canvas local-space
                Vector3 localHitPoint;
                world.Invert();
                Vector3.Transform(ref hitPoint, ref world, out localHitPoint);

                childSpaceLocation = new Vector2(localHitPoint);
                return(child.ContainsPoint(ref childSpaceLocation));
            }

            childSpaceLocation = Vector2.Zero;
            return(false);
        }
예제 #6
0
        public override void Draw(DeviceContext deviceContext)
        {
            System.Diagnostics.Debug.Assert(IsFullyLoaded);
            if (ShowBoundingBox > 0)
            {
                BoundingBox transformedBox = m_mesh.BoundingBox.TransformBoundingBox(m_transform.WorldMatrix);
                CRenderer.Instance.ActiveScene.DebugRenderer.DrawBox(transformedBox.Center, Quaternion.Identity, transformedBox.Size, Color.Red.ToColor4(), 0.0f, EDebugDrawCommandFlags.Wireframe);
            }

            if (ShowOrientedBoundingBox > 0)
            {
                OrientedBoundingBox obb = new OrientedBoundingBox(m_mesh.BoundingBox);
                obb.Transform(m_transform.WorldMatrix);
                obb.Transformation.Decompose(out Vector3 scale, out Quaternion rotation, out Vector3 translation);
                CRenderer.Instance.ActiveScene.DebugRenderer.DrawBox(translation, rotation, obb.Size * scale, Color.Green.ToColor4(), 0.0f, EDebugDrawCommandFlags.Wireframe);
            }

            if (m_overrideMaterial != null)
            {
                if (m_overrideMaterial.IsLoaded)
                {
                    m_mesh.RenderWithMaterial(deviceContext, m_overrideMaterial, m_transform);
                }
            }
            else
            {
                m_mesh.Render(deviceContext, m_transform);
            }
        }
 public OrientedBoundingBox(Vector2 center, Vector2 halfExtents, float rotation)
 {
     this             = new OrientedBoundingBox();
     this.Center      = center;
     this.HalfExtents = halfExtents;
     this.Rotation    = rotation;
 }
예제 #8
0
        /// <summary>
        /// Checks if given ray intersects with the oriented bounding wire box.
        /// </summary>
        /// <param name="box">The box.</param>
        /// <param name="ray">The ray.</param>
        /// <param name="distance">The result intersection distance.</param>
        /// <param name="viewPosition">The view position used to scale the wires thickness depending on the wire distance from the view.</param>
        /// <returns>True ray hits bounds, otherwise false.</returns>
        public static unsafe bool RayCastWire(ref OrientedBoundingBox box, ref Ray ray, out float distance, ref Vector3 viewPosition)
        {
            var corners = stackalloc Vector3[8];

            box.GetCorners(corners);

            var minDistance = Vector3.DistanceSquared(ref viewPosition, ref corners[0]);

            for (int i = 1; i < 8; i++)
            {
                minDistance = Mathf.Min(minDistance, Vector3.DistanceSquared(ref viewPosition, ref corners[i]));
            }
            minDistance = Mathf.Sqrt(minDistance);
            var margin = Mathf.Clamp(minDistance / 80.0f, 0.1f, 100.0f);

            if (GetWriteBox(ref corners[0], ref corners[1], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[0], ref corners[3], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[0], ref corners[4], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[1], ref corners[2], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[1], ref corners[5], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[2], ref corners[3], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[2], ref corners[6], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[3], ref corners[7], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[4], ref corners[5], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[4], ref corners[7], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[5], ref corners[6], margin).Intersects(ref ray, out distance) ||
                GetWriteBox(ref corners[6], ref corners[7], margin).Intersects(ref ray, out distance))
                return(true); }
예제 #9
0
        private static OrientedBoundingBox GetWriteBox(ref Vector3 min, ref Vector3 max, float margin)
        {
            var        box = new OrientedBoundingBox();
            Vector3    vec = max - min;
            Vector3    dir = Vector3.Normalize(vec);
            Quaternion orientation;

            if (Vector3.Dot(dir, Vector3.Up) >= 0.999f)
            {
                orientation = Quaternion.RotationAxis(Vector3.Left, Mathf.PiOverTwo);
            }
            else
            {
                orientation = Quaternion.LookRotation(dir, Vector3.Cross(Vector3.Cross(dir, Vector3.Up), dir));
            }
            Vector3 up = Vector3.Up * orientation;

            box.Transformation = Matrix.CreateWorld(min + vec * 0.5f, dir, up);
            Matrix.Invert(ref box.Transformation, out Matrix inv);
            Vector3 vecLocal = Vector3.TransformNormal(vec * 0.5f, inv);

            box.Extents.X = margin;
            box.Extents.Y = margin;
            box.Extents.Z = vecLocal.Z;
            return(box);
        }
예제 #10
0
    // SpatialMapping pathway only
    public void DrawFloorSpawnPoints(Vector3 requiredSize, float clearance, SurfacePlane plane)
    {
        OrientedBoundingBox bb          = plane.Plane.Bounds;
        Quaternion          orientation = (plane.transform.forward.y < 0) ? (plane.transform.rotation * Quaternion.FromToRotation(-Vector3.forward, Vector3.forward)) : plane.transform.rotation;
        // Note that xy in local plane coordinate system correspond to what would be xz in global space
        Vector3 halfExtents = new Vector3(requiredSize.x, requiredSize.z, requiredSize.y) * 0.5f;

        for (float y = -bb.Extents.y + halfExtents.y; y <= bb.Extents.y - halfExtents.y; y += 2 * halfExtents.y)
        {
            for (float x = -bb.Extents.x + halfExtents.x; x <= bb.Extents.x - halfExtents.x; x += 2 * halfExtents.x)
            {
                Vector3    center    = plane.transform.position + orientation * new Vector3(x, y, halfExtents.z + clearance);
                Collider[] colliders = Physics.OverlapBox(center, halfExtents, orientation, Layers.Instance.spatialMeshLayerMask);
                if (colliders.Length == 0)
                {
                    GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    cube.transform.parent                         = gameObject.transform; // level manager will be parent
                    cube.transform.localScale                     = 2 * halfExtents;
                    cube.transform.position                       = center;
                    cube.transform.transform.rotation             = orientation;
                    cube.GetComponent <Renderer>().material       = flatMaterial;
                    cube.GetComponent <Renderer>().material.color = Color.green;
                    cube.SetActive(true);
                }
            }
        }
    }
    private void UpdateWordResultPoses(Camera arCamera, IEnumerable <QCARManagerImpl.WordResultData> wordResults)
    {
        QCARAbstractBehaviour behaviour = (QCARAbstractBehaviour)UnityEngine.Object.FindObjectOfType(typeof(QCARAbstractBehaviour));

        if (behaviour == null)
        {
            Debug.LogError("QCAR Behaviour could not be found");
        }
        else
        {
            Rect viewportRectangle               = behaviour.GetViewportRectangle();
            bool videoBackGroundMirrored         = behaviour.VideoBackGroundMirrored;
            CameraDevice.VideoModeData videoMode = behaviour.GetVideoMode();
            foreach (QCARManagerImpl.WordResultData data2 in wordResults)
            {
                WordResultImpl impl        = (WordResultImpl)this.mTrackedWords[data2.id];
                Vector3        position    = arCamera.transform.TransformPoint(data2.pose.position);
                Quaternion     orientation = data2.pose.orientation;
                Quaternion     quaternion2 = (arCamera.transform.rotation * orientation) * Quaternion.AngleAxis(270f, Vector3.left);
                impl.SetPose(position, quaternion2);
                impl.SetStatus(data2.status);
                OrientedBoundingBox cameraFrameObb = new OrientedBoundingBox(data2.orientedBoundingBox.center, data2.orientedBoundingBox.halfExtents, data2.orientedBoundingBox.rotation);
                impl.SetObb(QCARRuntimeUtilities.CameraFrameToScreenSpaceCoordinates(cameraFrameObb, viewportRectangle, videoBackGroundMirrored, videoMode));
            }
            if (this.mWordPrefabCreationMode == WordPrefabCreationMode.DUPLICATE)
            {
                this.UpdateWordBehaviourPoses();
            }
        }
    }
예제 #12
0
 private OrientedBoundingBox GetBounds()
 {
     var obb = new OrientedBoundingBox(-Vector3.One / 2, Vector3.One / 2);
      obb.Scale(kCharacterSize);
      obb.Translate(position + kCharacterSize.Z * Vector3.UnitZ / 2);
      return obb;
 }
예제 #13
0
        private bool IntersectsChildContent(CanvasRootControl child, ref Ray ray, out Float2 childSpaceLocation)
        {
            // Inline bounds calculations (it will reuse world matrix)
            var bounds = new OrientedBoundingBox
            {
                Extents = new Vector3(child.Size * 0.5f, Mathf.Epsilon)
            };

            child.Canvas.GetWorldMatrix(out var world);
            Matrix.Translation((float)bounds.Extents.X, (float)bounds.Extents.Y, 0, out var offset);
            Matrix.Multiply(ref offset, ref world, out var boxWorld);
            boxWorld.Decompose(out bounds.Transformation);

            // Hit test
            if (bounds.Intersects(ref ray, out Vector3 hitPoint))
            {
                // Transform world-space hit point to canvas local-space
                world.Invert();
                Vector3.Transform(ref hitPoint, ref world, out Vector3 localHitPoint);

                childSpaceLocation = new Float2(localHitPoint);
                return(child.ContainsPoint(ref childSpaceLocation));
            }

            childSpaceLocation = Float2.Zero;
            return(false);
        }
예제 #14
0
 public TileBlock(Int16 topHeight, Int16 bottomHeight, Int32 index, OrientedBoundingBox topBoundingBox, OrientedBoundingBox bottomBoundingBox)
 {
     TopHeight         = topHeight;
     BottomHeight      = bottomHeight;
     Index             = index;
     TopBoundingBox    = topBoundingBox;
     BottomBoundingBox = bottomBoundingBox;
 }
예제 #15
0
    public static bool Contains(this OrientedBoundingBox thisBox, Vector3 pos)
    {
        Vector3 adjustedPos = Quaternion.Inverse(thisBox.Rotation) * (pos - thisBox.Center);

        return(adjustedPos.x <= thisBox.Extents.x && adjustedPos.x >= -thisBox.Extents.x &&
               adjustedPos.y <= thisBox.Extents.y && adjustedPos.y >= -thisBox.Extents.y &&
               adjustedPos.z <= thisBox.Extents.z && adjustedPos.z >= -thisBox.Extents.z);
    }
예제 #16
0
        protected override void UpdateHandles()
        {
            base.UpdateHandles();
            var boundingBox = new OrientedBoundingBox(Vector3.Zero, Vector3.Zero);    //PVInstance.ComputeBoundingBoxFromCollection(SelectionService.Selection);

            _marker.Size   = boundingBox.GetdEngineSize();
            _marker.CFrame = boundingBox.GetCFrame();
        }
예제 #17
0
    private bool CreateMarginVolumeObject(out GameObject marginVolume, out Vector3 centerPointOnFrontPlane, out Vector3 centerPointOnBackPlane, GameObject embedded, SurfacePlane plane)
    {
        BoxCollider embeddedOBB = embedded.GetComponent <BoxCollider>();

        if (null == embeddedOBB)
        {
            Debug.Log("ERROR: Embedded object " + embedded.name + " lacks a box collider");
            marginVolume            = null;
            centerPointOnFrontPlane = Vector3.zero;
            centerPointOnBackPlane  = Vector3.zero;
            return(true);
        }
        OrientedBoundingBox surfaceBounds = plane.Plane.Bounds;

        /*
         * Compute margin volume front (i.e., the actual surface) and back (onto
         * which spatial mesh triangles will be projected) planes based on embedded
         * object thickness.
         *
         * Note that the embedded object position is not in the center of the
         * object but rather at a point flush with the surface it will be embedded
         * in.
         */
        Vector3 intoSurfaceNormal  = -Vector3.Normalize(embeddedOBB.transform.forward);
        float   embeddedThickness  = embeddedOBB.size.z * embeddedOBB.transform.lossyScale.z + extraDisplacement;
        Vector3 embeddedPosOnPlane = plane.transform.InverseTransformPoint(embedded.transform.position);

        embeddedPosOnPlane.x    = 0;
        embeddedPosOnPlane.y    = 0;
        centerPointOnFrontPlane = plane.transform.TransformPoint(embeddedPosOnPlane);
        centerPointOnBackPlane  = centerPointOnFrontPlane + intoSurfaceNormal * embeddedThickness;
        Vector3 centerPoint = 0.5f * (centerPointOnFrontPlane + centerPointOnBackPlane);

        //Debug.Log("*** PlanePos: " + plane.transform.position + ", PlaneFwd: " + plane.transform.forward + ", Embed Point: " + embedded.transform.position.ToString("F2") + ", IntoNorm: " + intoSurfaceNormal.ToString("F2") + ", thick: " + embeddedThickness + ", embeddedPosOnPlane: " + embeddedPosOnPlane.ToString("F2") + ", centerFront: " + centerPointOnFrontPlane.ToString("F2") + ", centerBack: " + centerPointOnBackPlane.ToString("F2"));

        /*
         * Create a game object to describe the size, position, and orientation of
         * the margin volume we want to create.
         *
         * The box collider is something of a formality. The surface mesh
         * deformation procedure and OBB/mesh intersection tests use box colliders
         * to describe OBBs. Here, the box collider is made the same size as the
         * game object to which it is parented. The downstream intersection testing
         * code knows to properly scale the box based on its parent.
         */
        marginVolume = new GameObject("deformation-" + embedded.name);
        marginVolume.transform.position   = centerPoint;
        marginVolume.transform.localScale = new Vector3(2 * surfaceBounds.Extents.x, 2 * surfaceBounds.Extents.y, embeddedThickness);
        marginVolume.transform.rotation   = surfaceBounds.Rotation; // need to use surface plane rotation because x, y differ from obj's
        BoxCollider obb = marginVolume.AddComponent <BoxCollider>();

        obb.center  = Vector3.zero;
        obb.size    = Vector3.one;
        obb.enabled = false; // we do not actually want collision detection

        return(false);
    }
예제 #18
0
    private void CreateBulletHole(Vector3 position, Vector3 normal)
    {
        GameObject bulletHole = Instantiate(m_bulletHolePrefab, position, Quaternion.LookRotation(normal)) as GameObject;

        bulletHole.transform.parent = this.transform;
        OrientedBoundingBox obb = OBBMeshIntersection.CreateWorldSpaceOBB(bulletHole.GetComponent <BoxCollider>());

        SurfacePlaneDeformationManager.Instance.Embed(bulletHole, obb, position, () => { Debug.Log("Embed complete"); }, true);
    }
예제 #19
0
        public static void DrawBox(Color color, OrientedBoundingBox oob)
        {
#if DEBUG
            boxes.Add(new Box()
            {
                oob = oob, color = color
            });
#endif
        }
 public EmbedRequest(OrientedBoundingBox pObb, Vector3 pCenterPointOnFrontPlane, Vector3 pCenterPointOnBackPlane, GameObject pEmbedded, System.Action pOnComplete, bool pTempHighPriorityRender)
 {
     obb = pObb;
     centerPointOnFrontPlane = pCenterPointOnFrontPlane;
     centerPointOnBackPlane  = pCenterPointOnBackPlane;
     embedded               = pEmbedded;
     OnComplete             = pOnComplete;
     tempHighPriorityRender = pTempHighPriorityRender;
 }
예제 #21
0
        public bool Intersects(OrientedBoundingBox oob)
        {
            Matrix          invoob  = Matrix.Invert(oob.Transformation);
            BoundingFrustum frustum = new BoundingFrustum(oob.Transformation * View * Projection);

            BoundingBox bbox = new BoundingBox(-oob.Extents, oob.Extents);

            return(frustum.Intersects(ref bbox));
        }
예제 #22
0
 public static void Write(this NetOutgoingMessage message, OrientedBoundingBox volume)
 {
     message.Write((byte)volume.BoundingType);
     message.Write(volume.Center);
     message.Write(volume.XAxis);
     message.Write(volume.YAxis);
     message.Write(volume.ZAxis);
     message.Write(volume.Extents);
 }
예제 #23
0
        private static void Main(string[] args)
        {
            var random = new Random(1234);

            Vector3 GetPoint()
            {
                float Get()
                {
                    return((float)Math.Round((1.0d - 2.0d * random.NextDouble()) * 10));
                }

                return(new Vector3(Get(), Get(), Get()));
            }

            var points = Enumerable.Range(0, 10000).Select(s => GetPoint()).ToArray();


            var numEdges    = OrientedBoundingBox.NumEdges;
            var numFaces    = OrientedBoundingBox.NumFaces;
            var numVertices = OrientedBoundingBox.NumVertices;

            var box = new OrientedBoundingBox(Vector3.Zero, Vector3.Zero, Vector3.Right, Vector3.Up, Vector3.Forward);

            foreach (var point in points)
            {
                box.Enclose(point);
            }

            var b1 = box.Contains(Vector3.Zero);
            var b2 = box.Contains(new Vector3(100, 100, 100));
            var c1 = box.CornerPoint(0);
            var c2 = box.CornerPoint(7);
            var f1 = box.FacePoint(0, 0.0f, 0.0f);
            var f2 = box.FacePoint(0, 1.0f, 1.0f);
            var p1 = box.PointInside(0.0f, 0.0f, 0.0f);
            var p2 = box.PointInside(1.0f, 1.0f, 1.0f);
            var p3 = box.PointInside(0.5f, 0.5f, 0.5f);

            box.Translate(Vector3.One * +2);
            box.Translate(Vector3.One * -2);
            box.Scale(Vector3.Zero, Vector3.One * 0.5f);
            box.Scale(Vector3.Zero, Vector3.One * 2.0f);
            var d1 = box.Distance(Vector3.One * 20.0f);
            var d2 = box.Distance(Vector3.One * 30.0f);
            var e1 = box.PointOnEdge(0, 0.0f);
            var e2 = box.PointOnEdge(0, 1.0f);
            var e3 = box.PointOnEdge(0, 0.5f);
            var l1 = box.Edge(0);
            var l2 = box.Edge(1);
            var m1 = box.WorldToLocal();
            var m2 = box.LocalToWorld();
            var n1 = box.FacePlane(0);
            var n2 = box.FacePlane(1);
            var x1 = OrientedBoundingBox.OptimalEnclosing(points);
            var x2 = OrientedBoundingBox.BruteEnclosing(points);
        }
    private void CreateBulletHole(Vector3 position, Vector3 normal, SurfacePlane plane)
    {
        GameObject bulletHole = Instantiate(m_bulletHolePrefab, position, Quaternion.LookRotation(normal)) as GameObject;

        bulletHole.AddComponent <WorldAnchor>(); // does this do anything?
        bulletHole.transform.parent = this.transform;
        OrientedBoundingBox obb = OBBMeshIntersection.CreateWorldSpaceOBB(bulletHole.GetComponent <BoxCollider>());

        SurfacePlaneDeformationManager.Instance.Embed(bulletHole, obb, plane);
    }
예제 #25
0
        private void CalculateShape()
        {
            if (!Definition.RequiredSupport.HasValue)
            {
                return;
            }
            var shape = Definition.RequiredSupport.Value;
            var edge  = _bendy.Edges.FirstOrDefault();
            var curve = edge?.Curve;

            if (curve == null)
            {
                return;
            }
            _shapeDirty = false;
            _localBox   = BoundingBoxD.CreateInvalid();
            for (var i = 0; i < shape.Segments; i++)
            {
                Matrix matrix;
                {
                    var t   = (i + 0.5f) / shape.Segments;
                    var pos = (Vector3)Vector3D.Transform(curve.Sample(t), Entity.PositionComp.WorldMatrixNormalizedInv);
                    var up  = Vector3.TransformNormal(Vector3.Lerp((Vector3)edge.From.Up, (Vector3)edge.To.Up, t),
                                                      Entity.PositionComp.WorldMatrixNormalizedInv);
                    var tan = Vector3.TransformNormal((Vector3)curve.SampleDerivative(t), Entity.PositionComp.WorldMatrixNormalizedInv);
                    tan.Normalize();
                    up.Normalize();

                    matrix = Matrix.CreateWorld(Vector3.Zero, tan, up);
                }

                var box = BoundingBox.CreateInvalid();
                var mi  = Entity.PositionComp.WorldMatrixNormalizedInv * (MatrixD)Matrix.Invert(ref matrix);

                for (var j = 0; j <= 1; j++)
                {
                    var t    = (i + j) / (float)shape.Segments;
                    var pos  = curve.Sample(t);
                    var up   = Vector3.Lerp((Vector3)edge.From.Up, (Vector3)edge.To.Up, t);
                    var tan  = (Vector3)curve.SampleDerivative(t);
                    var norm = Vector3.Cross(up, tan);
                    norm.Normalize();

                    var nl = (Vector3)Vector3D.TransformNormal(norm, ref mi);
                    var ul = (Vector3)Vector3D.TransformNormal(up, ref mi);
                    var pl = (Vector3)Vector3D.Transform(pos, ref mi);

                    box.Include(pl + nl * shape.HalfWidth + ul * shape.VerticalOffset);
                    box.Include(pl - nl * shape.HalfWidth + ul * shape.VerticalOffset);
                }

                var obb = new OrientedBoundingBox(Vector3.Transform(box.Center, matrix), box.HalfExtents, Quaternion.CreateFromRotationMatrix(matrix));
                _localBox = _localBox.Include(obb.GetAABB());
            }
        }
        public bool IsInTrench(OrientedBoundingBox element)
        {
            var hit = false;

            foreach (var box in orientedBoundingBoxes)
            {
                hit |= box.Intersects(element);
            }

            return(hit);
        }
예제 #27
0
 public BoundedPlane(Transform xform)
 {
     Plane  = new Plane(xform.forward, xform.position);
     Bounds = new OrientedBoundingBox()
     {
         Center   = xform.position,
         Extents  = xform.localScale / 2,
         Rotation = xform.rotation
     };
     Area = Bounds.Extents.x * Bounds.Extents.y;
 }
예제 #28
0
    // Creates an oriented bounding box from the box collider in *world* coordinates
    public static OrientedBoundingBox CreateWorldSpaceOBB(BoxCollider collider)
    {
        OrientedBoundingBox obb = new OrientedBoundingBox()
        {
            Center   = collider.transform.TransformPoint(collider.center),
            Rotation = collider.transform.rotation,
            Extents  = 0.5f * new Vector3(collider.transform.lossyScale.x * collider.size.x, collider.transform.lossyScale.y * collider.size.y, collider.transform.lossyScale.z * collider.size.z)
        };

        return(obb);
    }
예제 #29
0
 public SurfacePlane(PlaneTypes type, Plane plane, OrientedBoundingBox bounds, TextMeshPro tag, Transform parent)
 {
     Type     = type;
     Plane    = plane;
     Bounds   = bounds;
     Area     = ((bounds.Extents.x * 2) * (bounds.Extents.y * 2));
     Tag      = GameObject.Instantiate(tag, parent);
     Tag.text = Type.ToString();
     Tag.transform.localPosition = bounds.Center;
     Tag.transform.eulerAngles   = new Vector3(bounds.Rotation.eulerAngles.x, bounds.Rotation.eulerAngles.y, 0);
 }
예제 #30
0
    public static void Encapsulate(this OrientedBoundingBox thisBox, Vector3 pos)
    {
        if (!Contains(thisBox, pos))
        {
            Vector3 adjustedPos = (pos - thisBox.Center);

            Vector3 newCenter  = thisBox.Center;
            Vector3 newExtents = thisBox.Extents;

            float diff;
            if (adjustedPos.x > thisBox.Extents.x)
            {
                diff          = adjustedPos.x - thisBox.Extents.x;
                newExtents.x += diff / 2;
                newCenter.x  += diff / 2;
            }
            else if (adjustedPos.x < -thisBox.Extents.x)
            {
                diff          = Mathf.Abs(-thisBox.Extents.x - adjustedPos.x);
                newExtents.x += diff / 2;
                newCenter.x  -= diff / 2;
            }

            if (adjustedPos.y > thisBox.Extents.y)
            {
                diff          = adjustedPos.y - thisBox.Extents.y;
                newExtents.y += diff / 2;
                newCenter.y  += diff / 2;
            }
            else if (adjustedPos.y < -thisBox.Extents.y)
            {
                diff          = Mathf.Abs(-thisBox.Extents.y - adjustedPos.y);
                newExtents.y += diff / 2;
                newCenter.y  -= diff / 2;
            }

            if (adjustedPos.z > thisBox.Extents.z)
            {
                diff          = adjustedPos.z - thisBox.Extents.z;
                newExtents.z += diff / 2;
                newCenter.z  += diff / 2;
            }
            else if (adjustedPos.z < -thisBox.Extents.z)
            {
                diff          = Mathf.Abs(-thisBox.Extents.z - adjustedPos.z);
                newExtents.z += diff / 2;
                newCenter.z  -= diff / 2;
            }

            thisBox.Center  = newCenter;
            thisBox.Extents = newExtents;
        }
    }
예제 #31
0
    public void GenerateGameBoard(Vector3 requiredSize, float clearance, SurfacePlane plane)
    {
        OrientedBoundingBox bb          = plane.Plane.Bounds;
        Quaternion          orientation = (plane.transform.forward.y < 0) ? (plane.transform.rotation * Quaternion.FromToRotation(-Vector3.forward, Vector3.forward)) : plane.transform.rotation;
        // Note that xy in local plane coordinate system correspond to what would be xz in global space
        Vector3 halfExtents = new Vector3(requiredSize.x, requiredSize.z, requiredSize.y) * 0.5f;
        int     xpos        = 0;

        for (float y = -bb.Extents.y + halfExtents.y; y <= bb.Extents.y - halfExtents.y; y += 2 * halfExtents.y)
        {
            int ypos = 0;
            for (float x = -bb.Extents.x + halfExtents.x; x <= bb.Extents.x - halfExtents.x; x += 2 * halfExtents.x)
            {
                Vector3    center    = plane.transform.position + orientation * new Vector3(x, y, halfExtents.z + clearance);
                Collider[] colliders = Physics.OverlapBox(center, halfExtents, orientation);
                if (colliders.Length == 0)
                {
                    int        cellsFromCamera = 2;
                    GameObject cell;
                    if ((Math.Abs(Camera.main.transform.position.x - center.x) <= (2 * halfExtents.x) * cellsFromCamera) ||
                        (Math.Abs(Camera.main.transform.position.z - center.z) <= (2 * halfExtents.z) * cellsFromCamera))
                    {
                        Debug.Log("Within camera range, placing GamePiece");
                        cell = Instantiate(GamePiece, gameObject.transform, true);
                    }
                    else
                    {
                        //replace with fisher yates
                        int isMine = getrandom.Next(1, 3);
                        if (isMine == 1)
                        {
                            Debug.Log("Placing mine");
                            cell = Instantiate(Mine, gameObject.transform, true);
                        }
                        else
                        {
                            Debug.Log("Placing GamePiece");
                            cell = Instantiate(GamePiece, gameObject.transform, true);
                        }
                    }

                    //cell.transform.localScale = 2 * halfExtents;
                    cell.transform.position = center;
                    // might be more effecient to use a dictionary to locate cells than the gameObject.find
                    cell.transform.name = "cell:" + xpos.ToString() + "," + ypos.ToString();
                    cell.transform.transform.rotation = orientation;
                    cell.SetActive(true);
                }
                ypos++;
            }
            xpos++;
        }
    }
 public void Serialize(ref OrientedBoundingBox value)
 {
     Serialize(ref value.Extents);
     Serialize(ref value.Transformation);
 }
예제 #33
0
 void Start()
 {
     orientedBoundingBox = new OrientedBoundingBox(transform, GetComponent<Collider>());
 }
예제 #34
0
        public void Initialize()
        {
            var obb = new OrientedBoundingBox(-Vector3.One / 2, Vector3.One / 2);
             var gridletHeight = Cells.Max(c => c.Height);
             obb.Scale(new Vector3(XLength, YLength, gridletHeight));
             obb.Transform(Orientation);
             obb.Translate(new Vector3(X, Y, Z + gridletHeight / 2));
             this.OrientedBoundingBox = obb;

             // Setup Grid
             for (var x = 0; x < XLength; x++) {
            for (var y = 0; y < YLength; y++) {
               var cellIndex = x + y * XLength;
               var cellHeight = Cells[cellIndex].Height;
               var cellTransform = Matrix.Translation(0, 0, 0.5f) *
                                   Matrix.Scaling(1, 1, cellHeight) *
                                   Matrix.Translation(-XLength * 0.5f + x + 0.5f, -YLength * 0.5f + y + 0.5f, 0) *
                                   Orientation *
                                   Matrix.Translation(X, Y, Z);
               Cells[cellIndex].OrientedBoundingBox = new OrientedBoundingBox { Extents = Vector3.One / 2, Transformation = cellTransform };
            }
             }

             EdgeCells = Cells.Where(x => x.Flags.HasFlag(CellFlags.Edge)).ToArray();
        }
    /// <summary>
    /// Calculates the screen space parameters for an oriented bounding box (center, half extents, rotation) specified in camera frame coordinates.
    /// The calculation is based on the current screen orientation.
    /// </summary>
    public static OrientedBoundingBox CameraFrameToScreenSpaceCoordinates(OrientedBoundingBox cameraFrameObb, Rect bgTextureViewPortRect, bool isTextureMirrored, CameraDevice.VideoModeData videoModeData)
    {
        bool isPortrait = false;
        float obbRotation = 0.0f;
        switch (QCARRuntimeUtilities.ScreenOrientation)
        {
            case ScreenOrientation.Portrait:
                obbRotation += 90.0f;
                isPortrait = true;
                break;
            case ScreenOrientation.LandscapeRight:
                obbRotation += 180.0f;
                break;
            case ScreenOrientation.PortraitUpsideDown:
                obbRotation += 270.0f;
                isPortrait = true;
                break;
        }

        var scaleX = bgTextureViewPortRect.width / (isPortrait ? videoModeData.height : videoModeData.width);
        var scaleY = bgTextureViewPortRect.height / (isPortrait ? videoModeData.width : videoModeData.height);

        var center = CameraFrameToScreenSpaceCoordinates(cameraFrameObb.Center, bgTextureViewPortRect,
                                                         isTextureMirrored, videoModeData);
        var halfExtents = new Vector2(cameraFrameObb.HalfExtents.x * scaleX, cameraFrameObb.HalfExtents.y * scaleY);

        var rotation = cameraFrameObb.Rotation;
        if (isTextureMirrored) rotation = -rotation;
        rotation = rotation*180.0f/Mathf.PI + obbRotation;

        return new OrientedBoundingBox(center, halfExtents, rotation);
    }
    private void UpdateWordResultPoses(Camera arCamera, IEnumerable<QCARManagerImpl.WordResultData> wordResults)
    {
        QCARBehaviour qcarbehaviour = (QCARBehaviour) Object.FindObjectOfType(typeof (QCARBehaviour));
        if (qcarbehaviour == null)
        {
            Debug.LogError("QCAR Behaviour could not be found");
            return;
        }

        // required information to transform camera frame coordinates into screen space coordinates:
        Rect bgTextureViewPortRect = qcarbehaviour.GetViewportRectangle();
        bool isMirrored = qcarbehaviour.VideoBackGroundMirrored;
        CameraDevice.VideoModeData videoModeData = qcarbehaviour.GetVideoMode();

        foreach (var wrd in wordResults)
        {
            var wordResult = (WordResultImpl) mTrackedWords[wrd.id];

            var position = arCamera.transform.TransformPoint(wrd.pose.position);

            var wrdOrientation = wrd.pose.orientation;
            var rotation = arCamera.transform.rotation*
                           wrdOrientation*
                           Quaternion.AngleAxis(270, Vector3.left);

            wordResult.SetPose(position, rotation);
            wordResult.SetStatus(wrd.status);

            var obb = new OrientedBoundingBox(wrd.orientedBoundingBox.center, wrd.orientedBoundingBox.halfExtents,
                                              wrd.orientedBoundingBox.rotation);
            wordResult.SetObb(QCARRuntimeUtilities.CameraFrameToScreenSpaceCoordinates(obb, bgTextureViewPortRect,
                                                                                       isMirrored, videoModeData));
        }

        // update word behaviours if enabled:
        if (mWordPrefabCreationMode == WordPrefabCreationMode.DUPLICATE)
            UpdateWordBehaviourPoses();
    }
 public void SetObb(OrientedBoundingBox obb)
 {
     mObb = obb;
 }
예제 #38
0
        public void Initialize()
        {
            cube = GeometricPrimitive.Cube.New(graphicsDevice);
             var cubeBounds = new OrientedBoundingBox(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, 0.5f));
             cubeMesh = new RenderMesh {
            BoundingBox = cubeBounds,
            IndexBuffer = cube.IndexBuffer,
            IsIndex32Bits = cube.IsIndex32Bits,
            InputLayout = VertexInputLayout.New<VertexPositionNormalTexture>(0),
            ModelTransform = Matrix.Identity,
            VertexBuffer = cube.VertexBuffer
             };

             basicEffect = new BasicEffect(graphicsDevice);
             basicEffect.EnableDefaultLighting(); // enable default lightning, useful for quick prototyping

             var debugEffectCompilerResult = new EffectCompiler().CompileFromFile("shaders/debug_solid.hlsl", EffectCompilerFlags.Debug);
             debugEffect = new Effect(graphicsDevice, debugEffectCompilerResult.EffectData, graphicsDevice.DefaultEffectPool);
             debugBatch = new PrimitiveBatch<VertexPositionColor>(graphicsDevice);
        }
예제 #39
0
 public void DrawOrientedBoundingBox(OrientedBoundingBox obb, Vector4 color, float scale = 1.01f)
 {
     var worldMatrix = Matrix.Scaling(obb.Extents * 2) * Matrix.Scaling(scale) * obb.Transformation;
      DrawCube(worldMatrix, color, true);
 }
            public void SetVertices(OrientedBoundingBox boundingBox, GraphicsDevice Graphics)
            {
                //BoundingBoxBuffers boundingBoxBuffers = new BoundingBoxBuffers();
                this.device = Graphics;
                this.PrimitiveCount = 24;
                this.VertexCount = 48;
                VertexBuffer vertexBuffer = new VertexBuffer(device,
                    typeof(VertexPositionColor), this.VertexCount,
                    BufferUsage.WriteOnly);
                const float ratio = 5.0f;
                Vector3 xOffset = new Vector3((boundingBox.HalfExtent.X) / ratio, 0, 0);
                Vector3 yOffset = new Vector3(0, (boundingBox.HalfExtent.Y) / ratio, 0);
                Vector3 zOffset = new Vector3(0, 0, (boundingBox.HalfExtent.Z) / ratio);
                Vector3[] corners = boundingBox.GetRotatedCorners();

                // Corner 1.
                AddVertex(verticesList, corners[0]);
                AddVertex(verticesList, corners[1]);
                AddVertex(verticesList, corners[0]);
                AddVertex(verticesList, corners[4]);
                AddVertex(verticesList, corners[0]);
                AddVertex(verticesList, corners[3]);
                // Corner 2.
                AddVertex(verticesList, corners[1]);
                AddVertex(verticesList, corners[2]);
                AddVertex(verticesList, corners[1]);
                AddVertex(verticesList, corners[5]);
                AddVertex(verticesList, corners[1]);
                AddVertex(verticesList, corners[0]);
                // Corner 3.
                AddVertex(verticesList, corners[2]);
                AddVertex(verticesList, corners[3]);
                AddVertex(verticesList, corners[2]);
                AddVertex(verticesList, corners[6]);
                AddVertex(verticesList, corners[2]);
                AddVertex(verticesList, corners[1]);
                // Corner 4.
                AddVertex(verticesList, corners[3]);
                AddVertex(verticesList, corners[0]);
                AddVertex(verticesList, corners[3]);
                AddVertex(verticesList, corners[7]);
                AddVertex(verticesList, corners[3]);
                AddVertex(verticesList, corners[2]);
                // Corner 5.
                AddVertex(verticesList, corners[4]);
                AddVertex(verticesList, corners[5]);
                AddVertex(verticesList, corners[4]);
                AddVertex(verticesList, corners[0]);
                AddVertex(verticesList, corners[4]);
                AddVertex(verticesList, corners[7]);
                // Corner 6.
                AddVertex(verticesList, corners[5]);
                AddVertex(verticesList, corners[6]);
                AddVertex(verticesList, corners[5]);
                AddVertex(verticesList, corners[1]);
                AddVertex(verticesList, corners[5]);
                AddVertex(verticesList, corners[4]);
                // Corner 7.
                AddVertex(verticesList, corners[6]);
                AddVertex(verticesList, corners[7]);
                AddVertex(verticesList, corners[6]);
                AddVertex(verticesList, corners[2]);
                AddVertex(verticesList, corners[6]);
                AddVertex(verticesList, corners[5]);
                // Corner 8.
                AddVertex(verticesList, corners[7]);
                AddVertex(verticesList, corners[4]);
                AddVertex(verticesList, corners[7]);
                AddVertex(verticesList, corners[3]);
                AddVertex(verticesList, corners[7]);
                AddVertex(verticesList, corners[6]);

                vertexBuffer.SetData(verticesList.ToArray());
                this.Vertices = vertexBuffer;
                IndexBuffer indexBuffer = new IndexBuffer(device, IndexElementSize.SixteenBits, this.VertexCount,
                    BufferUsage.WriteOnly);
                indexBuffer.SetData(Enumerable.Range(0, this.VertexCount).Select(i => (short)i).ToArray());
                this.Indices = indexBuffer;
            }
 public BoundingBoxBuffers(OrientedBoundingBox boundingBox, GraphicsDevice Graphics, Color LineColor)
 {
     this.LineColor = LineColor;
     SetVertices(boundingBox, Graphics);
 }
 public void Initialize()
 {
     bounds = new OrientedBoundingBox(-Vector3.One / 2, Vector3.One / 2);
      bounds.Translate(new Vector3(0, 0, 2));
 }
예제 #43
0
 protected void IntersectionModule_Intialize()
 {
     Collider collider = GetComponentInChildren<Collider>();
     orientedBoundingBox = new OrientedBoundingBox(transform, collider);
     GenerateQuickCastTriangles();
 }
 public BoundingBoxBuffers(OrientedBoundingBox boundingBox, GraphicsDevice Graphics)
 {
     SetVertices(boundingBox, Graphics);
 }