コード例 #1
0
        public static bool Raycast(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, TriangleEpsilon epsilon = new TriangleEpsilon())
        {
            t = 0.0f;

            float rayEnter;
            Plane trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter) &&
                Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2, epsilon))
            {
                t = rayEnter;
                return(true);
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, trianglePlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OBB obb = Calc3DTriangleOBB(p0, p1, p2, trianglePlane.normal, epsilon);
                    return(BoxMath.Raycast(ray, obb.Center, obb.Size, obb.Rotation));
                }
            }

            return(false);
        }
コード例 #2
0
        public BoxFaceAreaDesc GetWorldSnapAreaDesc(BoxFace boxFace)
        {
            Vector3 boxSize = _snapAreaBounds[(int)boxFace].Size;

            boxSize = Vector3.Scale(boxSize, _gameObject.transform.lossyScale.Abs());

            return(BoxMath.GetBoxFaceAreaDesc(boxSize, boxFace));
        }
コード例 #3
0
        public static bool RaycastWire(Ray ray, out float t, Vector3 quadCenter, float quadWidth, float quadHeight, Vector3 quadRight, Vector3 quadUp, QuadEpsilon epsilon = new QuadEpsilon())
        {
            t = 0.0f;
            Vector3    quadNormal   = Vector3.Normalize(Vector3.Cross(quadRight, quadUp));
            Plane      quadPlane    = new Plane(quadNormal, quadCenter);
            Vector2    quadSize     = new Vector2(quadWidth, quadHeight);
            Quaternion quadRotation = Quaternion.LookRotation(quadNormal, quadUp);

            float rayEnter;

            if (quadPlane.Raycast(ray, out rayEnter))
            {
                Vector3        intersectPt  = ray.GetPoint(rayEnter);
                List <Vector3> cornerPoints = Calc3DQuadCornerPoints(quadCenter, quadSize, quadRotation);

                float distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.TopLeft], cornerPoints[(int)QuadCorner.TopRight]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.TopRight], cornerPoints[(int)QuadCorner.BottomRight]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.BottomRight], cornerPoints[(int)QuadCorner.BottomLeft]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distFromSegment = intersectPt.GetDistanceToSegment(cornerPoints[(int)QuadCorner.BottomLeft], cornerPoints[(int)QuadCorner.TopLeft]);
                if (distFromSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, quadPlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OBB quadOBB = Calc3DQuadOBB(quadCenter, quadSize, Quaternion.LookRotation(quadNormal, quadUp), epsilon);
                    return(BoxMath.Raycast(ray, quadOBB.Center, quadOBB.Size, quadOBB.Rotation));
                }
            }

            return(false);
        }
コード例 #4
0
        public void Encapsulate(OBB otherOBB)
        {
            var otherPts = BoxMath.CalcBoxCornerPoints(otherOBB.Center, otherOBB.Size, otherOBB.Rotation);

            Matrix4x4 transformMtx = Matrix4x4.TRS(Center, Rotation, Vector3.one);
            var       modelPts     = transformMtx.inverse.TransformPoints(otherPts);

            AABB modelAABB = new AABB(Vector3.zero, Size);

            modelAABB.Encapsulate(modelPts);

            Center = (Rotation * modelAABB.Center) + Center;
            Size   = modelAABB.Size;
        }
コード例 #5
0
        private void UpdateTransform(Camera camera)
        {
            Vector3            midAxisPos       = _sceneGizmo.SceneGizmoCamera.LookAtPoint;
            RTSceneGizmoCamera sceneGizmoCamera = _sceneGizmo.SceneGizmoCamera;
            Vector3            axisDirection    = _sceneGizmo.Gizmo.Transform.GetAxis3D(_axisDesc);

            _zoomFactorTransform.Position3D = midAxisPos;
            float zoomFactor = _cap.GetZoomFactor(camera);

            Vector3 midCapSize = _sceneGizmo.LookAndFeel.MidCapType == GizmoCap3DType.Box ?
                                 Vector3Ex.FromValue(SceneGizmoLookAndFeel.MidCapBoxSize * zoomFactor) : Vector3Ex.FromValue(SceneGizmoLookAndFeel.MidCapSphereRadius * 2.0f * zoomFactor);
            Vector3 midBoxFaceCenter = BoxMath.CalcBoxFaceCenter(midAxisPos, midCapSize, Quaternion.identity, _midAxisBoxFace);

            _cap.CapSlider3DInvert(axisDirection, midBoxFaceCenter);
        }
コード例 #6
0
        public static List <Vector3> CollectWorldSpriteVerts(Sprite sprite, Transform spriteTransform, OBB collectOBB)
        {
            List <Vector3> spriteWorldVerts = sprite.GetWorldVerts(spriteTransform);
            List <Vector3> collectedVerts   = new List <Vector3>(7);

            foreach (Vector3 vertPos in spriteWorldVerts)
            {
                if (BoxMath.ContainsPoint(vertPos, collectOBB.Center, collectOBB.Size, collectOBB.Rotation))
                {
                    collectedVerts.Add(vertPos);
                }
            }

            return(collectedVerts);
        }
コード例 #7
0
        public static List <Vector3> CollectModelSpriteVerts(Sprite sprite, AABB collectAABB)
        {
            Vector2[]      spriteModelVerts = sprite.vertices;
            List <Vector3> collectedVerts   = new List <Vector3>(7);

            foreach (Vector2 vertPos in spriteModelVerts)
            {
                if (BoxMath.ContainsPoint(vertPos, collectAABB.Center, collectAABB.Size, Quaternion.identity))
                {
                    collectedVerts.Add(vertPos);
                }
            }

            return(collectedVerts);
        }
コード例 #8
0
ファイル: SceneTree.cs プロジェクト: GastonBC/AECH-Treehouse
        public GameObjectRayHit RaycastSpriteObject(Ray ray, GameObject gameObject)
        {
            float t;
            OBB   worldOBB = ObjectBounds.CalcSpriteWorldOBB(gameObject);

            if (!worldOBB.IsValid)
            {
                return(null);
            }

            if (BoxMath.Raycast(ray, out t, worldOBB.Center, worldOBB.Size, worldOBB.Rotation))
            {
                return(new GameObjectRayHit(ray, gameObject, worldOBB.GetPointFaceNormal(ray.GetPoint(t)), t));
            }

            return(null);
        }
コード例 #9
0
        public static bool RaycastWire(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, TriangleEpsilon epsilon = new TriangleEpsilon())
        {
            t = 0.0f;

            float rayEnter;
            Plane trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter))
            {
                Vector3 intersectPt   = ray.GetPoint(rayEnter);
                float   distToSegment = intersectPt.GetDistanceToSegment(p0, p1);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distToSegment = intersectPt.GetDistanceToSegment(p1, p2);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }

                distToSegment = intersectPt.GetDistanceToSegment(p2, p0);
                if (distToSegment <= epsilon.WireEps)
                {
                    t = rayEnter;
                    return(true);
                }
            }

            if (epsilon.ExtrudeEps != 0.0f)
            {
                float dot = Vector3Ex.AbsDot(ray.direction, trianglePlane.normal);
                if (dot < ExtrudeEpsThreshold.Get)
                {
                    OBB obb = Calc3DTriangleOBB(p0, p1, p2, trianglePlane.normal, epsilon);
                    return(BoxMath.Raycast(ray, obb.Center, obb.Size, obb.Rotation));
                }
            }

            return(false);
        }
コード例 #10
0
ファイル: MeshTree.cs プロジェクト: GastonBC/AECH-Treehouse
        public List <Vector3> OverlapVerts(OBB obb, MeshTransform meshTransform)
        {
            if (!_isBuilt)
            {
                Build();
            }

            OBB           meshSpaceOBB = meshTransform.InverseTransformOBB(obb);
            HashSet <int> usedIndices  = new HashSet <int>();
            List <SphereTreeNode <MeshTriangle> > overlappedNodes = _tree.OverlapBox(meshSpaceOBB);

            if (overlappedNodes.Count == 0)
            {
                return(new List <Vector3>());
            }

            List <Vector3> overlappedVerts = new List <Vector3>(50);

            foreach (SphereTreeNode <MeshTriangle> node in overlappedNodes)
            {
                int          triangleIndex = node.Data.TriangleIndex;
                MeshTriangle triangleInfo  = _mesh.GetTriangle(triangleIndex);
                Vector3[]    modelVerts    = triangleInfo.Vertices;

                for (int ptIndex = 0; ptIndex < modelVerts.Length; ++ptIndex)
                {
                    int vertIndex = triangleInfo.GetVertIndex(ptIndex);
                    if (usedIndices.Contains(vertIndex))
                    {
                        continue;
                    }

                    Vector3 modelVert = modelVerts[ptIndex];
                    if (BoxMath.ContainsPoint(modelVert, meshSpaceOBB.Center, meshSpaceOBB.Size, meshSpaceOBB.Rotation))
                    {
                        overlappedVerts.Add(meshTransform.TransformPoint(modelVert));
                        usedIndices.Add(vertIndex);
                    }
                }
            }

            return(overlappedVerts);
        }
コード例 #11
0
ファイル: MeshTree.cs プロジェクト: youngbrett/TreehouseHack
        public List <Vector3> OverlapModelVerts(OBB modelOBB)
        {
            if (!_isBuilt)
            {
                Build();
            }

            HashSet <int> usedIndices     = new HashSet <int>();
            var           overlappedNodes = _tree.OverlapBox(modelOBB);

            if (overlappedNodes.Count == 0)
            {
                return(new List <Vector3>());
            }

            var overlappedVerts = new List <Vector3>(50);

            foreach (var node in overlappedNodes)
            {
                int          triangleIndex = node.Data.TriangleIndex;
                MeshTriangle triangleInfo  = _mesh.GetTriangle(triangleIndex);
                var          modelVerts    = triangleInfo.Vertices;

                for (int ptIndex = 0; ptIndex < modelVerts.Length; ++ptIndex)
                {
                    int vertIndex = triangleInfo.GetVertIndex(ptIndex);
                    if (usedIndices.Contains(vertIndex))
                    {
                        continue;
                    }

                    Vector3 modelVert = modelVerts[ptIndex];
                    if (BoxMath.ContainsPoint(modelVert, modelOBB.Center, modelOBB.Size, modelOBB.Rotation))
                    {
                        overlappedVerts.Add(modelVert);
                        usedIndices.Add(vertIndex);
                    }
                }
            }

            return(overlappedVerts);
        }
コード例 #12
0
        private void SnapToObjectHitPoint(GameObjectRayHit objectHit, SnapToPointMode snapMode)
        {
            if (snapMode == SnapToPointMode.Exact)
            {
                float distToPlane = new Plane(Normal, Vector3.zero).GetDistanceToPoint(objectHit.HitPoint);
                YOffset = distToPlane;
            }
            else
            {
                ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
                boundsQConfig.ObjectTypes = GameObjectType.Mesh;

                OBB worldOBB = ObjectBounds.CalcWorldOBB(objectHit.HitObject, boundsQConfig);
                if (worldOBB.IsValid)
                {
                    Plane          slicePlane = new Plane(Normal, worldOBB.Center);
                    Vector3        destPt     = worldOBB.Center;
                    List <Vector3> obbCorners = BoxMath.CalcBoxCornerPoints(worldOBB.Center, worldOBB.Size, worldOBB.Rotation);

                    float sign = Mathf.Sign(slicePlane.GetDistanceToPoint(objectHit.HitPoint));
                    if (sign > 0.0f)
                    {
                        int furthestPtInFront = slicePlane.GetFurthestPtInFront(obbCorners);
                        if (furthestPtInFront >= 0)
                        {
                            destPt = obbCorners[furthestPtInFront];
                        }
                    }
                    else
                    {
                        int furthestPtBehind = slicePlane.GetFurthestPtBehind(obbCorners);
                        if (furthestPtBehind >= 0)
                        {
                            destPt = obbCorners[furthestPtBehind];
                        }
                    }

                    float distToPlane = new Plane(Normal, Vector3.zero).GetDistanceToPoint(destPt);
                    YOffset = distToPlane;
                }
            }
        }
コード例 #13
0
        private void UpdateExtrudeSliderTransforms()
        {
            Vector3    center   = BoxCenter;
            Quaternion rotation = BoxRotation;

            _leftExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Left);
            _leftExtrude.SetDirection(-BoxRight);

            _rightExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Right);
            _rightExtrude.SetDirection(BoxRight);

            _upExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Top);
            _upExtrude.SetDirection(BoxUp);

            _bottomExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Bottom);
            _bottomExtrude.SetDirection(-BoxUp);

            _backExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Front);
            _backExtrude.SetDirection(-BoxLook);

            _frontExtrude.StartPosition = BoxMath.CalcBoxFaceCenter(center, _boxSize, rotation, BoxFace.Back);
            _frontExtrude.SetDirection(BoxLook);
        }
コード例 #14
0
        private List <AABB> BuildVertOverlapAABBs(GameObject gameObject, Sprite sprite, RTMesh rtMesh)
        {
            if (sprite == null && rtMesh == null)
            {
                return(new List <AABB>());
            }

            const float overlapAmount     = 0.2f;
            float       halfOverlapAmount = overlapAmount * 0.5f;
            AABB        modelAABB         = sprite != null?ObjectBounds.CalcSpriteModelAABB(gameObject) : rtMesh.AABB;

            Vector3        modelAABBSize  = modelAABB.Size;
            List <BoxFace> modelAABBFaces = BoxMath.AllBoxFaces;

            const float sizeEps = 0.001f;

            Vector3[] overlapAABBSizes = new Vector3[modelAABBFaces.Count];
            overlapAABBSizes[(int)BoxFace.Left]   = new Vector3(overlapAmount, modelAABBSize.y + sizeEps, modelAABBSize.z + sizeEps);
            overlapAABBSizes[(int)BoxFace.Right]  = new Vector3(overlapAmount, modelAABBSize.y + sizeEps, modelAABBSize.z + sizeEps);
            overlapAABBSizes[(int)BoxFace.Bottom] = new Vector3(modelAABBSize.x + sizeEps, overlapAmount, modelAABBSize.z + sizeEps);
            overlapAABBSizes[(int)BoxFace.Top]    = new Vector3(modelAABBSize.x + sizeEps, overlapAmount, modelAABBSize.z + sizeEps);
            overlapAABBSizes[(int)BoxFace.Back]   = new Vector3(modelAABBSize.x + sizeEps, modelAABBSize.y + sizeEps, overlapAmount);
            overlapAABBSizes[(int)BoxFace.Front]  = new Vector3(modelAABBSize.x + sizeEps, modelAABBSize.y + sizeEps, overlapAmount);

            var overlapAABBs = new List <AABB>();

            for (int boxFaceIndex = 0; boxFaceIndex < modelAABBFaces.Count; ++boxFaceIndex)
            {
                BoxFace modelAABBFace = modelAABBFaces[boxFaceIndex];
                Vector3 faceCenter    = BoxMath.CalcBoxFaceCenter(modelAABB.Center, modelAABB.Size, Quaternion.identity, modelAABBFace);
                Vector3 faceNormal    = BoxMath.CalcBoxFaceNormal(modelAABB.Center, modelAABB.Size, Quaternion.identity, modelAABBFace);
                Vector3 overlapCenter = faceCenter - faceNormal * halfOverlapAmount;
                overlapAABBs.Add(new AABB(overlapCenter, overlapAABBSizes[boxFaceIndex]));
            }

            return(overlapAABBs);
        }
コード例 #15
0
ファイル: ConeMath.cs プロジェクト: youngbrett/TreehouseHack
        public static bool Raycast(Ray ray, out float t, Vector3 coneBaseCenter, float coneBaseRadius, float coneHeight, Quaternion coneRotation, ConeEpsilon epsilon = new ConeEpsilon())
        {
            t = 0.0f;
            Ray coneSpaceRay = ray.InverseTransform(Matrix4x4.TRS(coneBaseCenter, coneRotation, Vector3.one));

            float   xzAABBSize = coneBaseRadius * 2.0f;
            Vector3 aabbSize   = new Vector3(xzAABBSize, coneHeight + epsilon.VertEps * 2.0f, xzAABBSize);

            if (!BoxMath.Raycast(coneSpaceRay, Vector3.up * coneHeight * 0.5f, aabbSize, Quaternion.identity))
            {
                return(false);
            }

            // We will first perform a preliminary check to see if the ray intersects the bottom cap of the cone.
            // This is necessary because the cone equation views the cone as infinite (i.e. no bottom cap), and
            // if we didn't perform this check, we would never be able to tell when the bottom cap was hit.
            float rayEnter;
            Plane bottomCapPlane = new Plane(-Vector3.up, Vector3.zero);

            if (bottomCapPlane.Raycast(coneSpaceRay, out rayEnter))
            {
                // If the ray intersects the plane of the bottom cap, we will calculate the intersection point
                // and if it lies inside the cone's bottom cap area, it means we have a valid intersection. We
                // store the t value and then return true.
                Vector3 intersectionPoint = coneSpaceRay.origin + coneSpaceRay.direction * rayEnter;
                if (intersectionPoint.magnitude <= coneBaseRadius)
                {
                    t = rayEnter;
                    return(true);
                }
            }

            // We need this for the calculation of the quadratic coefficients
            float ratioSquared = coneBaseRadius / coneHeight;

            ratioSquared *= ratioSquared;

            // Calculate the coefficients.
            // Note: The cone equation which was used is: (X^2 + Z^2) / ratioSquared = (Y - coneHeight)^2.
            //       Where X, Y and Z are the coordinates of the point along the ray: (Origin + Direction * t).xyz
            float a = coneSpaceRay.direction.x * coneSpaceRay.direction.x + coneSpaceRay.direction.z * coneSpaceRay.direction.z - ratioSquared * coneSpaceRay.direction.y * coneSpaceRay.direction.y;
            float b = 2.0f * (coneSpaceRay.origin.x * coneSpaceRay.direction.x + coneSpaceRay.origin.z * coneSpaceRay.direction.z - ratioSquared * coneSpaceRay.direction.y * (coneSpaceRay.origin.y - coneHeight));
            float c = coneSpaceRay.origin.x * coneSpaceRay.origin.x + coneSpaceRay.origin.z * coneSpaceRay.origin.z - ratioSquared * (coneSpaceRay.origin.y - coneHeight) * (coneSpaceRay.origin.y - coneHeight);

            // The intersection happnes only if the quadratic equation has solutions
            float t1, t2;

            if (MathEx.SolveQuadratic(a, b, c, out t1, out t2))
            {
                // Make sure the ray does not intersect the cone only from behind
                if (t1 < 0.0f && t2 < 0.0f)
                {
                    return(false);
                }

                // Make sure we are using the smallest positive t value
                if (t1 < 0.0f)
                {
                    float temp = t1;
                    t1 = t2;
                    t2 = temp;
                }
                t = t1;

                // Make sure the intersection point does not sit below the cone's bottom cap or above the cone's cap
                Vector3 intersectionPoint = coneSpaceRay.origin + coneSpaceRay.direction * t;
                if (intersectionPoint.y < -epsilon.VertEps || intersectionPoint.y > coneHeight + epsilon.VertEps)
                {
                    t = 0.0f;
                    return(false);
                }

                // The intersection point is valid
                return(true);
            }

            // If we reached this point, it means the ray does not intersect the cone in any way
            return(false);
        }
コード例 #16
0
ファイル: PrismMath.cs プロジェクト: GastonBC/AECH-Treehouse
        public static bool RaycastTriangular(Ray ray, out float t, Vector3 baseCenter,
                                             float baseWidth, float baseDepth, float topWidth, float topDepth, float height, Quaternion prismRotation)
        {
            t = 0.0f;
            if (baseWidth == 0.0f || baseDepth == 0.0f ||
                topWidth == 0.0f || topDepth == 0.0f || height == 0.0f)
            {
                return(false);
            }

            baseWidth = Mathf.Abs(baseWidth);
            baseDepth = Mathf.Abs(baseDepth);
            topWidth  = Mathf.Abs(topWidth);
            topDepth  = Mathf.Abs(topDepth);

            ray = ray.InverseTransform(Matrix4x4.TRS(baseCenter, prismRotation, Vector3.one));

            // Since the raycast calculations can be quite expensive for a prism, we will
            // first check if the ray intersects its AABB to quickly return false if no
            // intersection is found. If the ray does not intersect the AABB it can not
            // possibly intersect the prism.
            Vector3 aabbSize = Vector3.Max(new Vector3(baseWidth, height, baseDepth), new Vector3(topWidth, height, topDepth));

            if (!BoxMath.Raycast(ray, Vector3.up * height * 0.5f, aabbSize, Quaternion.identity))
            {
                return(false);
            }

            List <Vector3> cornerPoints  = CalcTriangPrismCornerPoints(Vector3.zero, baseWidth, baseDepth, topWidth, topDepth, height, Quaternion.identity);
            Vector3        baseLeftPt    = cornerPoints[(int)TriangularPrismCorner.BaseLeft];
            Vector3        baseRightPt   = cornerPoints[(int)TriangularPrismCorner.BaseRight];
            Vector3        baseForwardPt = cornerPoints[(int)TriangularPrismCorner.BaseForward];

            Vector3 topLeftPt    = cornerPoints[(int)TriangularPrismCorner.TopLeft];
            Vector3 topRightPt   = cornerPoints[(int)TriangularPrismCorner.TopRight];
            Vector3 topForwardPt = cornerPoints[(int)TriangularPrismCorner.TopForward];

            List <float> tValues = new List <float>(5);

            // Base triangle
            float rayEnter;

            if (TriangleMath.Raycast(ray, out rayEnter, baseLeftPt, baseRightPt, baseForwardPt))
            {
                tValues.Add(rayEnter);
            }

            // Top triangle
            if (TriangleMath.Raycast(ray, out rayEnter, topLeftPt, topForwardPt, topRightPt))
            {
                tValues.Add(rayEnter);
            }

            // Back face
            List <Vector3> facePoints = new List <Vector3>(4)
            {
                baseLeftPt, topLeftPt, topRightPt, baseRightPt
            };
            Vector3 faceNormal = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;

            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            // Left face
            // facePoints[0] = baseLeftPt;
            facePoints[1] = baseForwardPt;
            facePoints[2] = topForwardPt;
            facePoints[3] = topLeftPt;
            faceNormal    = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;
            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            // Right face
            facePoints[0] = baseRightPt;
            facePoints[1] = topRightPt;
            // facePoints[2] = topForwardPt;
            facePoints[3] = baseForwardPt;
            faceNormal    = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;
            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            if (tValues.Count == 0)
            {
                return(false);
            }

            tValues.Sort(delegate(float t0, float t1) { return(t0.CompareTo(t1)); });
            t = tValues[0];

            return(true);
        }
コード例 #17
0
ファイル: BoxGizmo.cs プロジェクト: youngbrett/TreehouseHack
        public override void OnGizmoAttemptHandleDragBegin(int handleId)
        {
            if (OwnsHandle(handleId))
            {
                _scaleFromCenter = Hotkeys.EnableCenterPivot.IsActive();
                _scaleDragWorkData.DragOrigin = BoxCenter;

                if (handleId == _leftTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = -BoxRight;
                    _scaleDragWorkData.AxisIndex   = 0;
                    _scaleDragWorkData.SnapStep    = Settings3D.XSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.x;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Right);
                }
                else
                if (handleId == _rightTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = BoxRight;
                    _scaleDragWorkData.AxisIndex   = 0;
                    _scaleDragWorkData.SnapStep    = Settings3D.XSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.x;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Left);
                }
                else
                if (handleId == _topTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = BoxUp;
                    _scaleDragWorkData.AxisIndex   = 1;
                    _scaleDragWorkData.SnapStep    = Settings3D.YSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.y;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Bottom);
                }
                else
                if (handleId == _bottomTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = -BoxUp;
                    _scaleDragWorkData.AxisIndex   = 1;
                    _scaleDragWorkData.SnapStep    = Settings3D.YSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.y;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Top);
                }
                else
                if (handleId == _frontTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = -BoxLook;
                    _scaleDragWorkData.AxisIndex   = 2;
                    _scaleDragWorkData.SnapStep    = Settings3D.ZSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.z;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Back);
                }
                else
                if (handleId == _backTick.HandleId)
                {
                    _scaleDragWorkData.Axis        = BoxLook;
                    _scaleDragWorkData.AxisIndex   = 2;
                    _scaleDragWorkData.SnapStep    = Settings3D.ZSnapStep;
                    _scaleDragWorkData.EntityScale = _targetHierarchyTransform.lossyScale.z;
                    _scalePivot = BoxMath.CalcBoxFaceCenter(BoxCenter, _boxSize, BoxRotation, BoxFace.Front);
                }

                if (_scaleFromCenter)
                {
                    _scalePivot = BoxCenter;
                }
                _scaleDrag.SetWorkData(_scaleDragWorkData);

                if (BoxUsage == Usage.ObjectScale && _targetHierarchyTransform != null)
                {
                    _dragBeginTargetTransformSnapshot.Snapshot(_targetHierarchyTransform);
                }
            }
        }
コード例 #18
0
 public bool IntersectsOBB(OBB otherOBB)
 {
     return(BoxMath.BoxIntersectsBox(_center, _size, _rotation, otherOBB.Center, otherOBB.Size, otherOBB.Rotation));
 }
コード例 #19
0
 public Vector3 GetClosestPoint(Vector3 point)
 {
     return(BoxMath.CalcBoxPtClosestToPt(point, _center, _size, _rotation));
 }
コード例 #20
0
 public List <Vector3> GetCornerPoints()
 {
     return(BoxMath.CalcBoxCornerPoints(_center, _size, _rotation));
 }
コード例 #21
0
 public List <Vector3> GetCornerPoints()
 {
     return(BoxMath.CalcBoxCornerPoints(_center, _size, Quaternion.identity));
 }
コード例 #22
0
 public override bool Raycast(Ray ray, out float t)
 {
     return(BoxMath.Raycast(ray, out t, _center, _size, _rotation, _epsilon));
 }
コード例 #23
0
 public bool ContainsPoint(Vector3 point)
 {
     return(BoxMath.ContainsPoint(point, _center, _size, _rotation, _epsilon));
 }
コード例 #24
0
        public bool Initialize(GameObject gameObject)
        {
            if (gameObject == null || _gameObject != null)
            {
                return(false);
            }

            Mesh   mesh   = gameObject.GetMesh();
            Sprite sprite = gameObject.GetSprite();

            if (mesh == null && sprite == null)
            {
                return(false);
            }

            bool useMesh = true;

            if (mesh == null)
            {
                useMesh = false;
            }

            RTMesh rtMesh = null;

            if (useMesh)
            {
                Renderer meshRenderer = gameObject.GetMeshRenderer();
                if (meshRenderer == null || !meshRenderer.enabled)
                {
                    useMesh = false;
                }

                rtMesh = RTMeshDb.Get.GetRTMesh(mesh);
                if (rtMesh == null)
                {
                    useMesh = false;
                }
            }
            if (rtMesh == null && sprite == null)
            {
                return(false);
            }

            List <AABB> vertOverlapAABBs = BuildVertOverlapAABBs(gameObject, useMesh ? null : sprite, useMesh ? rtMesh : null);

            if (vertOverlapAABBs.Count == 0)
            {
                return(false);
            }

            AABB modelAABB = useMesh ? rtMesh.AABB : ObjectBounds.CalcSpriteModelAABB(gameObject);
            var  aabbFaces = BoxMath.AllBoxFaces;

            _gameObject = gameObject;
            if (useMesh)
            {
                foreach (var aabbFace in aabbFaces)
                {
                    AABB           overlapAABB     = vertOverlapAABBs[(int)aabbFace];
                    List <Vector3> overlappedVerts = rtMesh.OverlapModelVerts(overlapAABB);
                    Plane          facePlane       = BoxMath.CalcBoxFacePlane(modelAABB.Center, modelAABB.Size, Quaternion.identity, aabbFace);
                    overlappedVerts = facePlane.ProjectAllPoints(overlappedVerts);
                    _snapAreaBounds[(int)aabbFace] = new AABB(overlappedVerts);
                    _snapAreaDesc[(int)aabbFace]   = BoxMath.GetBoxFaceAreaDesc(_snapAreaBounds[(int)aabbFace].Size, aabbFace);
                }
            }
            else
            {
                foreach (var aabbFace in aabbFaces)
                {
                    if (aabbFace != BoxFace.Front && aabbFace != BoxFace.Back)
                    {
                        AABB           overlapAABB     = vertOverlapAABBs[(int)aabbFace];
                        List <Vector3> overlappedVerts = ObjectVertexCollect.CollectModelSpriteVerts(sprite, overlapAABB);
                        Plane          facePlane       = BoxMath.CalcBoxFacePlane(modelAABB.Center, modelAABB.Size, Quaternion.identity, aabbFace);
                        overlappedVerts = facePlane.ProjectAllPoints(overlappedVerts);
                        _snapAreaBounds[(int)aabbFace] = new AABB(overlappedVerts);
                        _snapAreaDesc[(int)aabbFace]   = BoxMath.GetBoxFaceAreaDesc(_snapAreaBounds[(int)aabbFace].Size, aabbFace);
                    }
                    else
                    {
                        _snapAreaBounds[(int)aabbFace] = AABB.GetInvalid();
                        _snapAreaDesc[(int)aabbFace]   = BoxFaceAreaDesc.GetInvalid();
                    }
                }
            }

            return(true);
        }
コード例 #25
0
 public Vector3 GetFaceCenter(BoxFace boxFace)
 {
     return(BoxMath.CalcBoxFaceCenter(_center, _size, _rotation, boxFace));
 }
コード例 #26
0
 public bool ContainsPoint(Vector3 point)
 {
     return(BoxMath.ContainsPoint(point, _center, _size, Quaternion.identity));
 }
コード例 #27
0
        public static bool Raycast(Ray ray, out float t, Vector3 baseCenter, float baseWidth, float baseDepth, float height, Quaternion rotation)
        {
            t   = 0.0f;
            ray = ray.InverseTransform(Matrix4x4.TRS(baseCenter, rotation, Vector3.one));

            Vector3 aabbSize = new Vector3(baseWidth, height, baseDepth);

            if (!BoxMath.Raycast(ray, Vector3.up * height * 0.5f, aabbSize, Quaternion.identity))
            {
                return(false);
            }

            List <float> tValues = new List <float>(5);

            Plane basePlane = new Plane(Vector3.up, Vector3.zero);
            float rayEnter  = 0.0f;

            if (basePlane.Raycast(ray, out rayEnter) &&
                QuadMath.Contains3DPoint(ray.GetPoint(rayEnter), false, baseCenter, baseWidth, baseDepth, Vector3.right, Vector3.forward))
            {
                tValues.Add(rayEnter);
            }

            float   halfWidth     = 0.5f * baseWidth;
            float   halfDepth     = 0.5f * baseDepth;
            Vector3 tipPosition   = Vector3.up * height;
            Vector3 p0            = tipPosition;
            Vector3 p1            = Vector3.right * halfWidth - Vector3.forward * halfDepth;
            Vector3 p2            = p1 - Vector3.right * baseWidth;
            Plane   trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = Vector3.right * halfWidth + Vector3.forward * halfDepth;
            p2            = p1 - Vector3.forward * baseDepth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = -Vector3.right * halfWidth + Vector3.forward * halfDepth;
            p2            = p1 + Vector3.right * baseWidth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = -Vector3.right * halfWidth - Vector3.forward * halfDepth;
            p2            = p1 + Vector3.forward * baseDepth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            if (tValues.Count == 0)
            {
                return(false);
            }

            tValues.Sort(delegate(float t0, float t1) { return(t0.CompareTo(t1)); });
            t = tValues[0];

            return(true);
        }
コード例 #28
0
 public void Transform(Matrix4x4 transformMatrix)
 {
     BoxMath.TransformBox(_center, _size, transformMatrix, out _center, out _size);
 }
コード例 #29
0
        public void SetFaceCenter(BoxFace boxFace, Vector3 newCenter)
        {
            Vector3 currentFaceCenter = BoxMath.CalcBoxFaceCenter(_center, _size, _rotation, boxFace);

            Center = newCenter + (_center - currentFaceCenter);
        }
コード例 #30
0
        public static List <Vector3> CollectHierarchyVerts(GameObject root, BoxFace collectFace, float collectBoxScale, float collectEps)
        {
            List <GameObject> meshObjects   = root.GetMeshObjectsInHierarchy();
            List <GameObject> spriteObjects = root.GetSpriteObjectsInHierarchy();

            if (meshObjects.Count == 0 && spriteObjects.Count == 0)
            {
                return(new List <Vector3>());
            }

            ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig();
            boundsQConfig.ObjectTypes = GameObjectType.Mesh | GameObjectType.Sprite;

            OBB hierarchyOBB = ObjectBounds.CalcHierarchyWorldOBB(root, boundsQConfig);

            if (!hierarchyOBB.IsValid)
            {
                return(new List <Vector3>());
            }

            int     faceAxisIndex = BoxMath.GetFaceAxisIndex(collectFace);
            Vector3 faceCenter    = BoxMath.CalcBoxFaceCenter(hierarchyOBB.Center, hierarchyOBB.Size, hierarchyOBB.Rotation, collectFace);
            Vector3 faceNormal    = BoxMath.CalcBoxFaceNormal(hierarchyOBB.Center, hierarchyOBB.Size, hierarchyOBB.Rotation, collectFace);

            float   sizeEps         = collectEps * 2.0f;
            Vector3 collectAABBSize = hierarchyOBB.Size;

            collectAABBSize[faceAxisIndex]            = (hierarchyOBB.Size[faceAxisIndex] * collectBoxScale) + sizeEps;
            collectAABBSize[(faceAxisIndex + 1) % 3] += sizeEps;
            collectAABBSize[(faceAxisIndex + 2) % 3] += sizeEps;

            OBB collectOBB = new OBB(faceCenter + faceNormal * (-collectAABBSize[faceAxisIndex] * 0.5f + collectEps), collectAABBSize);

            collectOBB.Rotation = hierarchyOBB.Rotation;

            List <Vector3> collectedVerts = new List <Vector3>(80);

            foreach (GameObject meshObject in meshObjects)
            {
                Mesh   mesh   = meshObject.GetMesh();
                RTMesh rtMesh = RTMeshDb.Get.GetRTMesh(mesh);
                if (rtMesh == null)
                {
                    continue;
                }

                List <Vector3> verts = rtMesh.OverlapVerts(collectOBB, meshObject.transform);
                if (verts.Count != 0)
                {
                    collectedVerts.AddRange(verts);
                }
            }

            foreach (GameObject spriteObject in spriteObjects)
            {
                List <Vector3> verts = CollectWorldSpriteVerts(spriteObject.GetSprite(), spriteObject.transform, collectOBB);
                if (verts.Count != 0)
                {
                    collectedVerts.AddRange(verts);
                }
            }

            return(collectedVerts);
        }