/// <summary>
        /// Performs a raycast and returns a list of hits for all objects whose meshes
        /// are intersected by the specified ray.
        /// </summary>
        public List <GameObjectRayHit> RaycastAllMesh(Ray ray)
        {
            // First, we will gather the objects whos boxes are intersected by the ray. If
            // no such objects exist, we will return an empty list.
            List <GameObjectRayHit> allBoxHits = RaycastAllBox(ray);

            if (allBoxHits.Count == 0)
            {
                return(new List <GameObjectRayHit>());
            }

            // Now we will loop through all these objects and identify the ones whose meshes
            // are hit by the ray.
            var allMeshObjectHits = new List <GameObjectRayHit>(allBoxHits.Count);
            Octave3DMeshDatabase octave3DMeshDatabase = Octave3DMeshDatabase.Get();

            foreach (var boxHit in allBoxHits)
            {
                // Store the object for easy access
                GameObject hitObject = boxHit.HitObject;
                if (hitObject == null)
                {
                    continue;
                }
                if (!hitObject.activeInHierarchy)
                {
                    continue;
                }

                Renderer renderer = hitObject.GetComponent <Renderer>();
                if (!renderer.enabled)
                {
                    continue;
                }

                // Store the object's mesh. If the object doesn't have a mesh, we will ignore it
                Mesh objectMesh = hitObject.GetMeshFromFilterOrSkinnedMeshRenderer();
                if (objectMesh == null)
                {
                    continue;
                }

                // Check if the ray intersects the mesh
                Octave3DMesh octave3DMesh = octave3DMeshDatabase.GetOctave3DMesh(objectMesh);
                MeshRayHit   meshRayHit   = octave3DMesh.Raycast(ray, hitObject.transform.GetWorldMatrix());

                // If the mesh was hit by the ray, we will store the hit info inside the output array
                if (meshRayHit != null)
                {
                    allMeshObjectHits.Add(new GameObjectRayHit(ray, hitObject, null, meshRayHit, null, null));
                }
            }

            return(allMeshObjectHits);
        }
Example #2
0
        public override bool Raycast(Ray ray, out Octave3DColliderRayHit colliderRayHit)
        {
            colliderRayHit = null;
            MeshRayHit meshRayHit = Mesh.Raycast(ray, _meshTransform);

            if (meshRayHit != null)
            {
                colliderRayHit = new Octave3DColliderRayHit(ray, meshRayHit.HitEnter, meshRayHit.HitPoint, meshRayHit.HitNormal, this);
            }

            return(colliderRayHit != null);
        }
Example #3
0
        public GameObjectRayHit(Ray ray, GameObject hitObject, OrientedBoxRayHit objectBoxHit, MeshRayHit objectMeshHit, TerrainRayHit objectTerrainHit, SpriteRayHit objectSpriteHit)
        {
            _ray       = ray;
            _hitObject = hitObject;

            // Only one kind of entity can be registered as a hit, so we will take the first
            // non-null hit instance using the following priority: terrain, mesh, sprite, box.
            if (objectTerrainHit != null)
            {
                _objectTerrainHit = objectTerrainHit;
                _objectBoxHit     = null;
                _objectMeshHit    = null;
                _objectSpriteHit  = null;
            }
            else
            if (objectMeshHit != null)
            {
                _objectTerrainHit = null;
                _objectBoxHit     = null;
                _objectMeshHit    = objectMeshHit;
                _objectSpriteHit  = null;
            }
            else
            if (objectSpriteHit != null)
            {
                _objectTerrainHit = null;
                _objectBoxHit     = null;
                _objectMeshHit    = null;
                _objectSpriteHit  = objectSpriteHit;
            }
            if (objectBoxHit != null)
            {
                _objectTerrainHit = null;
                _objectBoxHit     = objectBoxHit;
                _objectMeshHit    = null;
                _objectSpriteHit  = null;
            }
        }
        public void UpdateForMouseMovement()
        {
            if (!_isActive)
            {
                return;
            }

            if (MouseButtonStates.Instance.IsMouseButtonDown(MouseButton.Left))
            {
                _state = ObjectVertexSnapSessionState.SnapToDestination;
            }
            else
            {
                _state = ObjectVertexSnapSessionState.SelectSourceVertex;
            }

            if (_state == ObjectVertexSnapSessionState.SelectSourceVertex)
            {
                if (_sourceObjects == null || _sourceObjects.Count == 0)
                {
                    _objectMask.ObjectCollectionMask.UnmaskAll();
                    MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                    if (cursorRayHit.WasAnObjectHit)
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            Octave3DMesh octaveMesh = meshRayHit.HitMesh;

                            Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix);

                            _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                            _sourceObject = objectRayHit.HitObject;
                            _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf());
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _sourceObject = objectRayHit.HitObject;
                                _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                                _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf());
                            }
                        }
                    }
                }
                else
                {
                    MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                    if (cursorRayHit.WasAnObjectHit)
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            Octave3DMesh octaveMesh = meshRayHit.HitMesh;

                            Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix);
                            _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                            }
                        }
                    }

                    foreach (var parent in _sourceParents)
                    {
                        _objectMask.ObjectCollectionMask.Mask(parent.GetAllChildrenIncludingSelf());
                    }
                }
            }
            else
            {
                MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                if (cursorRayHit.WasAnythingHit)
                {
                    bool useGridCellHit = false;
                    if (!cursorRayHit.WasAnObjectHit)
                    {
                        useGridCellHit = true;
                    }
                    else
                    if (cursorRayHit.WasAnObjectHit && cursorRayHit.WasACellHit)
                    {
                        float gridCellHitEnter = cursorRayHit.GridCellRayHit.HitEnter;
                        float objectHitEnter   = cursorRayHit.ClosestObjectRayHit.HitEnter;
                        if (gridCellHitEnter < Mathf.Max(0.0f, (objectHitEnter - 1e-3f)))
                        {
                            useGridCellHit = true;
                        }
                    }

                    if (useGridCellHit)
                    {
                        XZGridCell       hitCell  = cursorRayHit.GridCellRayHit.HitCell;
                        XZOrientedQuad3D cellQuad = hitCell.Quad;

                        _destinationObject   = null;
                        _destinationGridCell = hitCell;

                        _snapPosition = cellQuad.GetPointClosestToPoint(cursorRayHit.GridCellRayHit.HitPoint, true);
                        SnapToDestination();
                    }
                    else
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            _destinationObject = objectRayHit.HitObject;
                            Triangle3D destinationTriangle = meshRayHit.HitMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            destinationTriangle.TransformPoints(_destinationObject.transform.localToWorldMatrix);
                            _destinationGridCell = null;

                            _snapPosition = destinationTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                            SnapToDestination();
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _destinationGridCell = null;
                                _destinationObject   = objectRayHit.HitObject;

                                _snapPosition = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                                SnapToDestination();
                            }
                        }
                    }
                }
            }
        }