コード例 #1
0
        /////////////////////////////////////////

        public MeshRayTestOptimized(Vector3F[] vertices, int[] indices)
        {
            this.vertices = vertices;
            this.indices  = indices;

            if (vertices.Length != 0 && indices.Length != 0)
            {
                var bounds = Bounds.Cleared;
                foreach (var vertex in vertices)
                {
                    bounds.Add(vertex);
                }

                var initSettings = new OctreeContainer.InitSettings();
                initSettings.InitialOctreeBounds       = bounds;
                initSettings.OctreeBoundsRebuildExpand = Vector3.Zero;
                initSettings.MinNodeSize = bounds.GetSize() / 50;
                octreeContainer          = new OctreeContainer(initSettings);

                for (int nTriangle = 0; nTriangle < indices.Length / 3; nTriangle++)
                {
                    var vertex0 = vertices[indices[nTriangle * 3 + 0]];
                    var vertex1 = vertices[indices[nTriangle * 3 + 1]];
                    var vertex2 = vertices[indices[nTriangle * 3 + 2]];

                    var triangleBounds = new Bounds(vertex0);
                    triangleBounds.Add(vertex1);
                    triangleBounds.Add(vertex2);

                    octreeContainer.AddObject(triangleBounds, 1);
                }
            }
        }
コード例 #2
0
        protected override void OnSpaceBoundsUpdate(ref SpaceBounds newBounds)
        {
            base.OnSpaceBoundsUpdate(ref newBounds);

            //!!!!bounding sphere

            switch (Shape.Value)
            {
            case ShapeEnum.Box:
                newBounds = new SpaceBounds(GetBox().ToBounds());
                break;

            case ShapeEnum.Sphere:
                newBounds = new SpaceBounds(GetSphere());
                break;

            case ShapeEnum.Ray:
            {
                var    ray = GetRay();
                Bounds b   = new Bounds(ray.Origin);
                b.Add(ray.GetEndPoint());
                newBounds = new SpaceBounds(b);
            }
            break;
            }
        }
コード例 #3
0
ファイル: Capsule.cs プロジェクト: zwiglm/NeoAxisEngine
        public Bounds ToBounds()
        {
            Bounds result = new Bounds(Point1);

            result.Add(Point2);
            result.Expand(Radius);
            return(result);
        }
コード例 #4
0
        ////!!!!
        ///// <summary>Computes the convex hull of a polygon, in clockwise order in a Y-up
        ///// coordinate system (counterclockwise in a Y-down coordinate system).</summary>
        ///// <remarks>Uses the Monotone Chain algorithm, a.k.a. Andrew's Algorithm.</remarks>
        //public static List<Vector2> ComputeConvexHull( IEnumerable<Vector2> points )
        //{
        //	var list = new List<Vector2>( points );
        //	return ComputeConvexHull( list, true );
        //}
        //public static List<Vector2> ComputeConvexHull( List<Vector2> points, bool sortInPlace )//= false )
        //{
        //	if( !sortInPlace )
        //		points = new List<Vector2>( points );

        //	points.Sort( ( a, b ) => a.X == b.X ? a.Y.CompareTo( b.Y ) : ( a.X > b.X ? 1 : -1 ) );

        //	// Importantly, DList provides O(1) insertion at beginning and end
        //	List<Vector2> hull = new List<Vector2>();
        //	int L = 0, U = 0; // size of lower and upper hulls

        //	// Builds a hull such that the output polygon starts at the leftmost point.
        //	for( int i = points.Count - 1; i >= 0; i-- )
        //	{
        //		Vector2 p = points[ i ], p1;

        //		// build lower hull (at end of output list)
        //		while( L >= 2 && ( p1 = hull.Last ).Sub( hull[ hull.Count - 2 ] ).Cross( p.Sub( p1 ) ) >= 0 )
        //		{
        //			hull.RemoveAt( hull.Count - 1 );
        //			L--;
        //		}
        //		hull.PushLast( p );
        //		L++;

        //		// build upper hull (at beginning of output list)
        //		while( U >= 2 && ( p1 = hull.First ).Sub( hull[ 1 ] ).Cross( p.Sub( p1 ) ) <= 0 )
        //		{
        //			hull.RemoveAt( 0 );
        //			U--;
        //		}
        //		if( U != 0 ) // share the point added above, except in the first iteration
        //			hull.PushFirst( p );
        //		U++;
        //	}
        //	hull.RemoveAt( hull.Count - 1 );
        //	return hull;
        //}

        void GetDirectionalLightShadowsCascadeHullPlanes(ViewportRenderingContext context, LightItem lightItem, int cascadeIndex, out Plane[] planes, out Bounds bounds)
        {
            var cornerPoints = GetDirectionalLightShadowsCameraCornerPoints(context, cascadeIndex);

            var inputVertices = new List <Vector3>(cornerPoints.Length * 2);

            inputVertices.AddRange(cornerPoints);
            foreach (var point in cornerPoints)
            {
                inputVertices.Add(point - lightItem.data.Rotation.ToQuaternion().GetForward() * ShadowDirectionalLightExtrusionDistance);
            }

            var projectMatrix   = lightItem.data.Rotation.ToQuaternion().GetInverse();
            var unprojectMatrix = lightItem.data.Rotation.ToQuaternion();

            var projected2D = new Vector2[cornerPoints.Length];

            for (int n = 0; n < projected2D.Length; n++)
            {
                var p = projectMatrix * cornerPoints[n];
                projected2D[n] = new Vector2(p.Y, p.Z);
            }

            var convex = MathAlgorithms.GetConvexByPoints(projected2D);

            var planesList = new List <Plane>(convex.Count);

            for (int n = 0; n < convex.Count; n++)
            {
                var p1 = convex[n];
                var p2 = convex[(n + 1) % convex.Count];

                var u1 = unprojectMatrix * new Vector3(0, p1.X, p1.Y);
                var u2 = unprojectMatrix * new Vector3(0, p2.X, p2.Y);
                var u3 = unprojectMatrix * new Vector3(1, p2.X, p2.Y);

                planesList.Add(Plane.FromPoints(u1, u3, u2));
            }
            planes = planesList.ToArray();

            ////!!!!глючит
            //ConvexHullAlgorithm.Create( inputVertices.ToArray(), out planes );

            bounds = Bounds.Cleared;
            foreach (var p in inputVertices)
            {
                bounds.Add(p);
            }
        }
コード例 #5
0
ファイル: Capsule.cs プロジェクト: zwiglm/NeoAxisEngine
        public bool Contains(Vector3 point)
        {
            if (Point1 != Point2)
            {
                double radiusSquared = Radius * Radius;

                if ((Point1 - point).LengthSquared() <= radiusSquared)
                {
                    return(true);
                }
                if ((Point2 - point).LengthSquared() <= radiusSquared)
                {
                    return(true);
                }

                Vector3 projectPoint;
                MathAlgorithms.ProjectPointToLine(ref Point1, ref Point2, ref point, out projectPoint);

                Bounds pointsBounds = new Bounds(Point1);
                pointsBounds.Add(Point2);

                if (pointsBounds.Contains(projectPoint))
                {
                    if ((projectPoint - point).LengthSquared() <= radiusSquared)
                    {
                        return(true);
                    }
                }

                return(false);
            }
            else
            {
                return(new Sphere(Point1, Radius).Contains(point));
            }
        }
コード例 #6
0
        protected override void OnSpaceBoundsUpdate(ref SpaceBounds newBounds)
        {
            base.OnSpaceBoundsUpdate(ref newBounds);

            if (rigidBody != null)
            {
                var tr        = Transform.Value;
                var trNoScale = new Transform(tr.Position, tr.Rotation);

                Bounds bounds = Bounds.Cleared;
                foreach (var p in rigidBodyLocalPoints)
                {
                    bounds.Add(trNoScale * new Vector3(p, 0));
                }

                if (!bounds.IsCleared())
                {
                    bounds.Expand(new Vector3(0, 0, 0.001));

                    var b = new SpaceBounds(bounds);
                    newBounds = SpaceBounds.Merge(newBounds, b);
                }
            }
        }
コード例 #7
0
ファイル: Capsule.cs プロジェクト: zwiglm/NeoAxisEngine
 public void ToBounds(out Bounds result)
 {
     result = new Bounds(Point1);
     result.Add(Point2);
     result.Expand(Radius);
 }
コード例 #8
0
        public Bounds GetVisualBounds()
        {
            var transform = Transform.Value;
            var pos       = transform.Position;
            var rot       = transform.Rotation;

            var bounds = new Bounds(pos);

            double aspectRatio = AspectRatio;

            if (aspectRatio == 0)
            {
                aspectRatio = 1;
            }

            double halfWidth;
            double halfHeight;

            if (Projection.Value == ProjectionType.Perspective)
            {
                double tan = Math.Tan(FieldOfView.Value.InRadians() / 2);
                halfWidth  = tan * FarClipPlane.Value * aspectRatio;
                halfHeight = tan * FarClipPlane.Value;
            }
            else
            {
                halfWidth  = Height * .5 * aspectRatio;
                halfHeight = Height * .5;
            }
            var frustum       = new Frustum(true, Projection.Value, pos, rot, NearClipPlane.Value, FarClipPlane.Value, halfWidth, halfHeight);
            var frustumPoints = frustum.Points;

            switch (Projection.Value)
            {
            case ProjectionType.Perspective:
            {
                var points = new Vector3[8];
                {
                    for (int n = 4; n < 8; n++)
                    {
                        double distance = GetVisualLength();
                        var    dir      = (frustumPoints[n] - pos).GetNormalize() * distance;
                        var    p        = pos + dir * distance;
                        points[n] = p;
                    }
                }

                for (int n = 4; n < 8; n++)
                {
                    bounds.Add(points[n]);
                }
            }
            break;

            case ProjectionType.Orthographic:
            {
                //!!!!
            }
            break;
            }

            return(bounds);
        }
コード例 #9
0
        protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            var epsilon = 0.0001f;

            //clear data
            processedVertices = null;
            processedIndices  = null;
            processedTrianglesToSourceIndex = null;

            //get source geometry
            if (!GetSourceData(out var sourceVertices, out var sourceIndices))
            {
                return(null);
            }

            //check valid data
            if (CheckValidData)
            {
                if (!MathAlgorithms.CheckValidVertexIndexBuffer(sourceVertices.Length, sourceIndices, false))
                {
                    Log.Info("Component_CollisionShape2D_Mesh: CreateShape: Invalid source data.");
                    return(null);
                }
            }

            //process geometry
            if (MergeEqualVerticesRemoveInvalidTriangles)
            {
                MathAlgorithms.MergeEqualVerticesRemoveInvalidTriangles(sourceVertices, sourceIndices, epsilon, epsilon, out processedVertices, out processedIndices, out processedTrianglesToSourceIndex);
            }
            else
            {
                processedVertices = sourceVertices;
                processedIndices  = sourceIndices;
            }

            if (ShapeType.Value == ShapeTypeEnum.Auto && ParentRigidBody.MotionType.Value == Component_RigidBody2D.MotionTypeEnum.Dynamic && MathAlgorithms.IsMeshConvex(processedVertices, processedIndices, epsilon) || ShapeType.Value == ShapeTypeEnum.Convex)
            {
                //convex

                var    points = new List <Vector2>(processedVertices.Length);
                Bounds bounds = Bounds.Cleared;
                foreach (var p in processedVertices)
                {
                    var p2 = shapeTransform * new Vector3(p.ToVector2(), 0);
                    points.Add(p2.ToVector2());
                    bounds.Add(p2);
                    //points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );
                }

                var fixtures = new List <Fixture>();
                {
                    var currentList = new Vertices(points.Count);

                    for (int vertex = 0; vertex < points.Count; vertex++)
                    {
                        currentList.Add(Physics2DUtility.Convert(points[vertex]));

                        if (currentList.Count == Settings.MaxPolygonVertices)
                        {
                            fixtures.Add(body.CreatePolygon(currentList, 0));

                            currentList = new Vertices();
                            currentList.Add(Physics2DUtility.Convert(points[0]));
                            currentList.Add(Physics2DUtility.Convert(points[vertex]));
                        }
                    }

                    if (currentList.Count >= 3)
                    {
                        fixtures.Add(body.CreatePolygon(currentList, 0));
                    }
                }

                //rigidBodyLocalPoints
                {
                    var r = bounds.ToRectangle();
                    rigidBodyLocalPoints.Add(r.LeftTop);
                    rigidBodyLocalPoints.Add(r.RightTop);
                    rigidBodyLocalPoints.Add(r.RightBottom);
                    rigidBodyLocalPoints.Add(r.LeftBottom);
                }

                if (fixtures.Count != 0)
                {
                    return(fixtures.ToArray());
                }

                //var points = new List<Vector2>();
                //foreach( var p in processedVertices )
                //	points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );

                //var vertices = new Vertices( points.Count );
                //foreach( var p in points )
                //	vertices.Add( Physics2DUtility.Convert( p ) );

                //if( vertices.Count > 1 )
                //	return new Fixture[] { body.CreatePolygon( vertices, 0 ) };
            }
            else
            {
                //chain shapes

                var       fixtures = new List <Fixture>();
                Rectangle bounds   = Rectangle.Cleared;


                //!!!!

                ESet <(Vector2, Vector2)> wasAdded = new ESet <(Vector2, Vector2)>();

                void Add(Vector2 p1, Vector2 p2)
                {
                    if (p1 != p2 && !wasAdded.Contains((p1, p2)) && !wasAdded.Contains((p2, p1)))
                    {
                        wasAdded.Add((p1, p2));

                        fixtures.Add(body.CreateEdge(Physics2DUtility.Convert(p1), Physics2DUtility.Convert(p2)));

                        bounds.Add(p1);
                        bounds.Add(p2);
                    }
                }

                for (int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++)
                {
                    var v0 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 0]];
                    var v1 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 1]];
                    var v2 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 2]];

                    Add(v0.ToVector2(), v1.ToVector2());
                    Add(v1.ToVector2(), v2.ToVector2());
                    Add(v2.ToVector2(), v0.ToVector2());
                }



                //rectangle

                //for( int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++ )
                //{
                //	//!!!!slowly shapeTransform *
                //	var v0 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 0 ] ];
                //	var v1 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 1 ] ];
                //	var v2 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 2 ] ];
                //	bounds.Add( v0 );
                //	bounds.Add( v1 );
                //	bounds.Add( v2 );
                //}

                //var vertices = new Vertices();
                //var r = bounds.ToRectangle();
                //vertices.Add( Physics2DUtility.Convert( r.LeftTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightBottom ) );
                //vertices.Add( Physics2DUtility.Convert( r.LeftBottom ) );



                //local points for space bounds calculation
                rigidBodyLocalPoints.Add(bounds.LeftTop);
                rigidBodyLocalPoints.Add(bounds.RightTop);
                rigidBodyLocalPoints.Add(bounds.RightBottom);
                rigidBodyLocalPoints.Add(bounds.LeftBottom);

                return(fixtures.ToArray());

                //return new Fixture[] { body.CreateLoopShape( vertices ) };
            }

            return(null);
        }
コード例 #10
0
            public bool Intersects(ref Bounds bounds)
            {
                if (Bounds != null && Planes != null)
                {
                    //Planes + Bounds
                    if (Bounds.Value.Intersects(ref bounds) || BoundsPlanesIntersects(bounds, Planes))
                    {
                        return(true);
                    }
                }
                else if (Planes != null)
                {
                    //Planes
                    if (BoundsPlanesIntersects(bounds, Planes))
                    {
                        return(true);
                    }
                }
                else if (Frustum != null)
                {
                    //Frustum
                    Bounds frustumBounds = new Bounds(Frustum.Points[0]);
                    for (int n = 1; n < 8; n++)
                    {
                        frustumBounds.Add(Frustum.Points[n]);
                    }
                    if (frustumBounds.Intersects(ref bounds) || BoundsPlanesIntersects(bounds, Frustum.Planes))
                    {
                        return(true);
                    }
                }
                else if (Bounds != null)
                {
                    //Bounds
                    if (Bounds.Value.Intersects(ref bounds))
                    {
                        return(true);
                    }
                }
                else if (Box != null)
                {
                    //Box
                    if (Box.Value.Intersects(ref bounds))
                    {
                        return(true);
                    }
                }
                else if (Sphere != null)
                {
                    //Sphere
                    if (Sphere.Value.Intersects(ref bounds))
                    {
                        return(true);
                    }
                }
                else if (Ray != null)
                {
                    //Ray
                    if (bounds.Intersects(Ray.Value))
                    {
                        return(true);
                    }
                }

                return(false);
            }