public void Add(MyTriangle_Vertexes triangle, Vector3 normal, ref MyPlane rightPlane, ref MyPlane upPlane, float decalScale, float alpha, bool alphaBlendByAngle, ref BoundingSphere decalSphere)
        {
            float alpha0 = alpha;
            float alpha1 = alpha;
            float alpha2 = alpha;

            if (alphaBlendByAngle == true)
            {
                alpha0 *= GetAlphaByDistance(ref triangle.Vertex0, ref decalSphere);
                alpha1 *= GetAlphaByDistance(ref triangle.Vertex1, ref decalSphere);
                alpha2 *= GetAlphaByDistance(ref triangle.Vertex2, ref decalSphere);
            }

            if ((alpha0 <= 0.0f) && (alpha1 <= 0.0f) && (alpha2 <= 0.0f))
            {
                //  Decal would be totaly transparent so it doesn't make sense to draw it
                return;
            }

            MyCockpitGlassDecalTriangle decalTriangle = m_triangles.Allocate();
            if (decalTriangle == null) 
                return;

            decalTriangle.Position0 = triangle.Vertex0;
            decalTriangle.Position1 = triangle.Vertex1;
            decalTriangle.Position2 = triangle.Vertex2;

            //  Texture coords
            decalTriangle.TexCoord0 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref upPlane));
            decalTriangle.TexCoord1 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref upPlane));
            decalTriangle.TexCoord2 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref upPlane));

            //  Normal
            normal = MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.Normalize(normal);
            decalTriangle.Normal0 = normal;
            decalTriangle.Normal1 = normal;
            decalTriangle.Normal2 = normal;

            decalTriangle.Alpha012.X = alpha0;
            decalTriangle.Alpha012.Y = alpha1;
            decalTriangle.Alpha012.Z = alpha2;

            //  Time created
            decalTriangle.CreatedTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;
        }
Beispiel #2
0
        //  Add decal and all surounding triangles for model intersection
        static void AddDecalModel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle,
                                  ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyDecalsForPhysObjectsTriangleBuffer decalsBuffer = m_decalsForModels.GetTrianglesBuffer(intersection.Entity, decalTexture);

            //  If we get null, buffer is full so no new decals can't be placed
            if (decalsBuffer == null)
            {
                return;
            }

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            BoundingSphere decalSphere = new BoundingSphere(intersection.IntersectionPointInObjectSpace, decalSize);

            m_neighbourTriangles.Clear();

            intersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, intersection.NormalInObjectSpace, MyDecalsConstants.MAX_NEIGHBOUR_ANGLE, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);

            int trianglesToAdd = m_neighbourTriangles.Count;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd))
            {
                Vector3 normalSum = Vector3.Zero;
                if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                {
                    normalSum  = CalculateDominantNormal(m_neighbourTriangles);
                    normalSum *= decalNormalOffset;
                }

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                    {
                        var triangle = m_neighbourTriangles[i];
                        triangle.Vertexes.Vertex0 += normalSum;
                        triangle.Vertexes.Vertex1 += normalSum;
                        triangle.Vertexes.Vertex2 += normalSum;
                        m_neighbourTriangles[i]    = triangle;
                    }

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.Triangle.InputTriangleNormal,
                                     ref rightPlane, ref upPlane, decalScale, decalSize, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInObjectSpace, emissivity);
                }
            }
        }
Beispiel #3
0
        public void CylinderSnapping()
        {
            // Get Boundary2
            if (boundaryPoints_2d == null)
            {
                boundaryPoints_2d = GetBoundaryPoints(mark);
            }
            List <MyVector2> boundary2 = ExtractOutline(edgeImage, boundaryPoints_2d);

            // Project  2D edge points
            //topCircle = new MyCircle(topCircle.Center, topCircle.Radius, -topCircle.Normal);
            MyVector3 normal       = topCircle.Normal.Cross(this.camera.target).Cross(topCircle.Normal);
            MyPlane   sectionPlane = new MyPlane(topCircle.Center, normal);

            boundary3 = Proj2dToPlane(sectionPlane, boundary2);

            topCircle = CiriFixTopCircle(topCircle, boundary3);

            // UpdateCircleNormal
            //        foreach (var pbondary3 in pbondary3)
            //        {

            //        }
            //        if (topCircle.Center)
            //{

            //}

            // Algorithm Init Params
            double offset = topCircle.Radius / 50;

            cur_p    = topCircle.Center - offset * topCircle.Normal;
            cur_dire = 1.0 * topCircle.Normal;
            MyVector3 cur_dire_new = new MyVector3(cur_dire);
            MyVector3 cur_p_new    = new MyVector3(-1 * cur_p);

            Insection1 = new MyVector3(1, 1, 1);
            Insection2 = new MyVector3(0, 0, 0);
            int       norInsec    = -1;
            int       notNorInsec = -1;
            MyVector3 tangential1 = new MyVector3(1, 1, 1);
            MyVector3 tangential2 = new MyVector3(1, 1, 1);

            List <MyCircle> CircleLists = new List <MyCircle>();

            CircleLists.Add(topCircle);     // Fix first circle

            int    iter = 0;
            double r    = double.MaxValue;

            System.Console.WriteLine(Insection1.Dot(tangential2));
            System.Console.WriteLine(Math.Cos(2.0 / 3.0 * Math.PI));
            int MaxInter = 1000;

            GeneratedCenters = new List <MyVector3>();
            List <double>    radius  = new List <double>();
            List <double>    weights = new List <double>();
            List <MyVector3> dires   = new List <MyVector3>();

            while (--MaxInter > 0)                                           //
            {
                if (Insection1 == Insection2)                                // 交点一直保持相同
                {
                    System.Console.WriteLine("Warning: Insection is same!"); // 半径过小
                    break;
                }
                if (cur_dire.Dot(cur_dire_new) < 0)                                 // 移动方向反向
                {
                    System.Console.WriteLine("Warning: Move Direction!");
                    break;
                }
                if (cur_p + offset * cur_dire == cur_p_new)                         // 中心点没有移动
                {
                    System.Console.WriteLine("Warning: Center not move!");
                    break;
                }

                RayTracein3DPlane(boundary3,
                                  cur_p_new,
                                  cur_dire_new.Cross(sectionPlane.Normal()),
                                  sectionPlane.Normal(),
                                  out norInsec,
                                  out notNorInsec);
                System.Console.WriteLine("{0} , {1}",
                                         MyVector3.Distance(boundary3[norInsec], cur_p_new),
                                         MyVector3.Distance(boundary3[notNorInsec], cur_p_new));
                test1 = new Line3(boundary3[norInsec], cur_p_new - boundary3[norInsec]);
                test2 = new Line3(boundary3[notNorInsec], cur_p_new - boundary3[notNorInsec]);

                if (MyVector3.Distance(boundary3[norInsec], cur_p_new) < topCircle.Radius / 20 || // close to bottom
                    MyVector3.Distance(boundary3[notNorInsec], cur_p_new) < topCircle.Radius / 20)
                {
                    System.Console.WriteLine("Warning: Close to bottom!");
                    break;
                }

                if (tangential1.Dot(tangential2) < Math.Cos(2.0 / 3.0 * Math.PI))   //切线相向
                {
                    System.Console.WriteLine("Warning: tangential get oppsite direction!");
                    break;
                }
                if (r < 0.0001)
                {
                    System.Console.WriteLine("Warning: Radius is too small!");      // 半径过小
                    break;
                }
                //if (MyVector3.Distance(cur_p, cur_p_new) )
                //{
                //    System.Console.WriteLine("Warning: Radius is too small!");    // 半径过小
                //    break;
                //}

                if (iter != 0)
                {
                    //offset = 1 / MyVector3.Distance(cur_p, cur_p_new) * 0.000001 + 0.5 * offset;
                    offset = topCircle.Radius / 20;
                    //System.Console.WriteLine("{0}", offset);
                    cur_dire = cur_dire_new;
                    cur_p    = cur_p_new + offset * cur_dire;
                    CircleLists.Add(new MyCircle(cur_p, r, cur_dire));

                    // Get Data for Fit
                    double weight = Math.Abs(cur_dire_new.Dot(cur_dire));
                    GeneratedCenters.Add(cur_p_new);
                    weights.Add(weight);
                    radius.Add(r);
                    dires.Add(cur_dire);
                }

                // Step1: Get IntersectionPoitn
                RayTracein3DPlane(boundary3, cur_p, cur_dire, sectionPlane.Normal(), out norInsec, out notNorInsec);

                // Step2 : Get Two Local Tangential
                Insection1  = boundary3[norInsec];
                Insection2  = boundary3[notNorInsec];
                tangential1 = GetLocalTangential(norInsec, boundary3, cur_dire);
                tangential2 = GetLocalTangential(notNorInsec, boundary3, cur_dire);

                // Visualization
                setdirecLine = new Line3(cur_p, cur_dire);
                setLine1     = new Line3(Insection1, tangential1);
                setLine2     = new Line3(Insection2, tangential2);

                // Step3 : Get New Cur Direction and Cur Point
                cur_dire_new = (tangential1 + tangential2) / 2;
                RayTracein3DPlane(boundary3, cur_p, cur_dire_new, sectionPlane.Normal(), out norInsec, out notNorInsec);
                cur_p_new = (boundary3[norInsec] + boundary3[notNorInsec]) / 2;
                r         = 0.5 * MyVector3.Distance(boundary3[norInsec], boundary3[notNorInsec]);

                iter++;
                this.view.Refresh();
            }

            // Fit centers and radius;
            GeneratedCenters = FittingCentersCurve(GeneratedCenters, weights);
            int inter = 1;

            while (inter-- > 0)
            {
                radius = FittRadius(radius);
            }

            // ReBuild Object
            CircleLists.Clear();
            CircleLists.Add(topCircle);         // Fix first circle
            for (int i = 0; i < GeneratedCenters.Count; i++)
            {
                CircleLists.Add(new MyCircle(GeneratedCenters[i], radius[i], dires[i]));
            }

            CurveCyliner = new SweepMesh(CircleLists);
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, List<MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3? referenceNormalVector = null;
            float? maxAngle = null;

            var aabb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);
            m_overlappedTriangles.Clear();

           // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery"); // This code is called recursively and cause profiler to lag
            bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles);
           // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles");  // This code is called recursively and cause profiler to lag

                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles) return;

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);
                    
                    //gi_aabb.CollideTriangleExact

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                            triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                            triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normal retTriangle;
                                    retTriangle.Vertexes = triangle;
                                    retTriangle.Normal = calculatedTriangleNormal;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
Beispiel #5
0
        //  Add decal and all surounding triangles for voxel intersection
        static void AddDecalVoxel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle,
            ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyVoxelMap voxelMap = (MyVoxelMap)intersection.Entity;

            MyMwcVector3Int renderCellCoord = voxelMap.GetVoxelRenderCellCoordinateFromMeters(ref intersection.IntersectionPointInWorldSpace);
            BoundingSphere decalBoundingSphere = new BoundingSphere(intersection.IntersectionPointInWorldSpace, decalSize);

            //  If whole decal can't fit inside of render cell, we won't add any of its triangles. This is because
            //  when hiding/removing triangles after explosion, it is easier to check only one render cell.
            BoundingBox renderCellBoundingBox;
            voxelMap.GetRenderCellBoundingBox(ref renderCellCoord, out renderCellBoundingBox);

            // TODO simon - commented as an experiment. If there are bugs with decals on voxels, remove the comment below
            //if (renderCellBoundingBox.Contains(decalBoundingSphere) != ContainmentType.Contains) return;

            //  If we get null, buffer is full so no new decals can't be placed
            MyDecalsForVoxelsTriangleBuffer decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(voxelMap, ref renderCellCoord, decalTexture, ref renderCellBoundingBox);
            if (decalsBuffer == null) return;

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            m_neighbourTriangles.Clear();
            //intersection.VoxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, intersection.TriangleHelperIndex, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);
            voxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles, false);

            int trianglesToAdd = m_neighbourTriangles.Count;// +1;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd) == true)
            {
                var normalSum = CalculateDominantNormal(m_neighbourTriangles);
                normalSum *= decalNormalOffset;

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    var triangle = m_neighbourTriangles[i];
                    triangle.Vertexes.Vertex0 += normalSum;
                    triangle.Vertexes.Vertex1 += normalSum;
                    triangle.Vertexes.Vertex2 += normalSum;
                    m_neighbourTriangles[i] = triangle;

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.NormalInWorldSpace, ref rightPlane,
                        ref upPlane, decalScale, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInWorldSpace, emissivity);
                }
            }
        }
        protected override bool Interact(bool staticCollision)
        {
            if (staticCollision)
            {
                //MyCommonDebugUtils.AssertDebug(false, "Sphere-voxel static interaction called! And that's wrong.");
            }
            else
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("SphereVoxelInteraction");

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Transformations");

                if (RBElement1.GetElementType() != MyRBElementType.ET_SPHERE)
                    SwapElements();

                Matrix matrix0 = RBElement1.GetGlobalTransformation();
                Matrix matrix1 = RBElement2.GetGlobalTransformation();

                float sphereRadius = ((MyRBSphereElement)RBElement1).Radius;

                Vector3 body0Pos = matrix0.Translation; // sphere pos
                Vector3 body1Pos = matrix1.Translation;

                float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                float epsylon = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon;

                Vector3 newBody0Pos = matrix0.Translation + GetRigidBody1().LinearVelocity * dt;

                float sphereTolR = epsylon + sphereRadius;
                float sphereTolR2 = sphereTolR * sphereTolR;

                MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc();
                int numCollPts = 0;

                Vector3 collNormal = Vector3.Zero;

                //var colDetThroughVoxels = MyConstants.SPHERE_VOXELMAP_COLDET_THROUGH_VOXELS;
                var colDetThroughVoxels = !GetRigidBody1().ReadFlag(RigidBodyFlag.RBF_COLDET_THROUGH_VOXEL_TRIANGLES);

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                if (colDetThroughVoxels)
                {
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("colDetThroughVoxels");

                    BoundingSphere newSphere;
                    newSphere.Center = newBody0Pos;
                    newSphere.Radius = sphereRadius;

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PoolList.Get");
                    using (var voxelMapsFounded = PoolList<MyVoxelMap>.Get())
                    {
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere");

                        MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref newSphere, voxelMapsFounded, null);

                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("foreach (MyVoxelMap voxelMap in voxelMapsFounded)");
                        foreach (MyVoxelMap voxelMap in voxelMapsFounded)
                        {
                            if (voxelMap != null)
                            {
                                //  We will iterate only voxels contained in the bounding box of new sphere, so here we get min/max corned in voxel units
                                MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                                    newSphere.Center.X - newSphere.Radius,
                                    newSphere.Center.Y - newSphere.Radius,
                                    newSphere.Center.Z - newSphere.Radius));
                                MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                                    newSphere.Center.X + newSphere.Radius,
                                    newSphere.Center.Y + newSphere.Radius,
                                    newSphere.Center.Z + newSphere.Radius));
                                voxelMap.FixVoxelCoord(ref minCorner);
                                voxelMap.FixVoxelCoord(ref maxCorner);

                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("for loop");

                                MyMwcVector3Int tempVoxelCoord;
                                for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
                                {
                                    for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                                    {
                                        for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                                        {
                                            byte voxelContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                                            //  Ignore voxels bellow the ISO value (empty, partialy empty...)
                                            if (voxelContent < MyVoxelConstants.VOXEL_ISO_LEVEL) continue;

                                            Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);

                                            //float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF;
                                            float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_RADIUS;

                                            //  If distance to voxel border is less than sphere radius, we have a collision
                                            //  So now we calculate normal vector and penetration depth but on OLD sphere
                                            float newDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize;
                                            if (newDistanceToVoxel < (epsylon + newSphere.Radius))
                                            {
                                                Vector3 collisionN = MyMwcUtils.Normalize(voxelPosition - body0Pos);

                                                if (numCollPts < MyPhysicsConfig.MaxContactPoints)
                                                {
                                                    //  Calculate penetration depth, but from old sphere (not new)
                                                    float oldDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize;
                                                    float oldPenetrationDepth = oldDistanceToVoxel - sphereRadius;

                                                    // Vector3 pt = body0Pos + sphereRadius * collisionN;
                                                    Vector3 pt = voxelPosition - collisionN * (voxelSize - epsylon);

                                                    collPtArray[numCollPts++] = new MySmallCollPointInfo(pt - body0Pos, pt - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, oldPenetrationDepth, pt);
                                                }

                                                collNormal -= collisionN;
                                            }
                                        }
                                    }
                                }

                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                            }
                        }

                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                    }

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }
                else //if (colDetThroughVoxels)
                {
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ColDet triangles");

                    int optimalIterationCount = (int)(GetRigidBody1().LinearVelocity.Length() * dt / sphereRadius);
                    int maxIndex = (int)MathHelper.Min(MathHelper.Max(optimalIterationCount, 1), 16);

                    for (int i = 0; i < maxIndex; i++)
                    {

                        float velocityAdd = GetRigidBody1().LinearVelocity.Length() * dt / (float)maxIndex;

                        Vector3 interpolatedPosition = body0Pos + GetRigidBody1().LinearVelocity * dt * i / (float)maxIndex;

                        BoundingSphere newSphere;
                        newSphere.Center = interpolatedPosition;
                        newSphere.Radius = sphereRadius;

                        int numTriangles;

                        BoundingBox bb = BoundingBox.CreateFromSphere(newSphere);
                        MyVoxelMaps.GetPotentialTrianglesForColDet(out numTriangles, ref bb);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            MyColDetVoxelTriangle meshTriangle = MyVoxelMaps.PotentialColDetTriangles[iTriangle]; // mesh.GetTriangle(potentialTriangles[iTriangle]);


                            MyTriangle_Vertex_Normal triangle = new MyTriangle_Vertex_Normal();
                            triangle.Vertexes.Vertex0 = meshTriangle.Vertex0;
                            triangle.Vertexes.Vertex1 = meshTriangle.Vertex1;
                            triangle.Vertexes.Vertex2 = meshTriangle.Vertex2;


                            // skip too narrow triangles causing instability
                            if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            if ((triangle.Vertexes.Vertex1 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            MyPlane plane = new MyPlane(ref triangle.Vertexes);

                            Vector3? pt = MyUtils.GetSphereTriangleIntersection(ref newSphere, ref plane, ref triangle.Vertexes);
                            if (pt == null)
                                continue;


                            Vector3 collisionN = plane.Normal;

                            // skip triangle in case the normal is in wrong dir (narrow walls)  
                            Vector3 tempV = (newBody0Pos - pt.Value);
                            if (Vector3.Dot(collisionN, tempV) >= 0.8f * tempV.Length())  // equivalent to dot(collisionN, normalize(tempV)) > 0.8f, but works for zero vectors
                            {
                                continue;
                            }

                            float depth = Vector3.Distance(pt.Value, body0Pos) - sphereRadius;

                            if (numCollPts < MyPhysicsConfig.MaxContactPoints)
                            {
                                // since impulse get applied at the old position
                                Vector3 p2 = pt.Value;

                                collPtArray[numCollPts++] = new MySmallCollPointInfo(p2 - body0Pos, p2 - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, depth, p2);
                            }

                            collNormal += collisionN;
                        }
                    }

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }

                if (numCollPts > 0)
                {
                    MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numCollPts);
                }
                MyContactInfoCache.FreeStackAlloc(collPtArray);

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            return false;
        }
Beispiel #7
0
        public static void Update()
        {
            //  Update only if sun wind is active
            if (IsActive == false)
            {
                return;
            }

            //?
            float dT = ((float)MyMinerGame.TotalGamePlayTimeInMilliseconds - (float)m_timeLastUpdate) / 1000.0f;

            m_timeLastUpdate = MyMinerGame.TotalGamePlayTimeInMilliseconds;

            if ((MyGuiScreenGamePlay.Static.IsEditorActive() && !MyGuiScreenGamePlay.Static.IsIngameEditorActive()) || MyMinerGame.IsPaused())
            {
                return;
            }

            m_deltaTime += dT;

            float traveledDistance = m_speed * m_deltaTime;

            //  If sun wind finished its way, we will turn it off
            if (traveledDistance >= MySunWindConstants.SUN_WIND_LENGTH_TOTAL)
            {
                IsActive = false;
                StopCue();
                return;
            }

            Vector3 campos = MyCamera.Position;

            //  This is plane that goes through sun wind, it's in its middle
            m_planeMiddle       = new MyPlane(m_initialSunWindPosition + m_directionFromSunNormalized * traveledDistance, m_directionFromSunNormalized);
            m_distanceToSunWind = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeMiddle);

            //  We make sure that sound moves always on line that goes through camera. So it's not in the middle of sun wind, more like middle where is camera.
            //  Reason is that I want the sound always go through camera.
            m_positionOnCameraLine = MyCamera.Position - m_directionFromSunNormalized * m_distanceToSunWind;

            Vector3 positionFront = m_positionOnCameraLine + m_directionFromSunNormalized * 5000;
            Vector3 positionBack  = m_positionOnCameraLine + m_directionFromSunNormalized * -5000;

            m_planeFront = new MyPlane(ref positionFront, ref m_directionFromSunNormalized);
            m_planeBack  = new MyPlane(ref positionBack, ref m_directionFromSunNormalized);

            float distanceToFrontPlane = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeFront);
            float distanceToBackPlane  = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeBack);


            Vector3 positionOfSound;

            if ((distanceToFrontPlane <= 0) && (distanceToBackPlane >= 0))
            {
                positionOfSound = MyCamera.Position;
            }
            else if (distanceToFrontPlane > 0)
            {
                positionOfSound = positionFront;
            }
            else
            {
                positionOfSound = positionBack;
            }

            //  Update position of sound. It works like this: we hear coming sound, then we are in the sound and then we hear it coming out.
            MyAudio.UpdateCuePosition(m_burningCue, positionOfSound, m_directionFromSunNormalized, -m_downVector, m_directionFromSunNormalized * m_speed);
            //MySounds.UpdateCuePosition(m_burningCue, positionOfSound, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero);

            //MyLogManager.WriteLine("positionOfSound: " + MyUtils.GetFormatedVector3(positionOfSound, 3));
            //MyLogManager.WriteLine("m_directionFromSunNormalized: " + MyUtils.GetFormatedVector3(m_directionFromSunNormalized, 3));
            //MyLogManager.WriteLine("m_downVector: " + MyUtils.GetFormatedVector3(m_downVector, 3));

            Position = positionOfSound;

            //  Shake player's head
            float distanceToSound;

            Vector3.Distance(ref positionOfSound, ref campos, out distanceToSound);
            float shake = 1 - MathHelper.Clamp(distanceToSound / 1000, 0, 1);

            if (MySession.PlayerShip != null)
            {
                MySession.PlayerShip.IncreaseHeadShake(
                    MathHelper.Lerp(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MIN,
                                    MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MAX, shake));
            }

            for (int i = 0; i < m_sunwindEntities.Count;)
            {
                if (m_sunwindEntities[i].Closed)
                {
                    m_sunwindEntities.RemoveAtFast(i);
                }
                else
                {
                    i++;
                }
            }

            //  Apply force to all objects that aren't static and are hit by sun wind (ignoring voxels and large ships)
            MyEntities.ApplySunWindForce(m_sunwindEntities, ref m_planeFront, ref m_planeBack, DoNotIgnoreTheseTypes, ref m_directionFromSunNormalized);

            //  Start small billboards
            if (m_distanceToSunWind <= MySunWindConstants.SWITCH_LARGE_AND_SMALL_BILLBOARD_DISTANCE)
            {
                Debug.Assert(m_computedMaxDistances == MySunWindConstants.SMALL_BILLBOARDS_SIZE.X * MySunWindConstants.SMALL_BILLBOARDS_SIZE.Y, "Not all small billboard MaxDistances are computed!");
                m_smallBillboardsStarted = true;
            }

            ComputeMaxDistances();
        }
Beispiel #8
0
        public static void Update()
        {
            //  Update only if sun wind is active
            if (IsActive == false) return;

            //?
            float dT = ((float)MyMinerGame.TotalGamePlayTimeInMilliseconds - (float)m_timeLastUpdate) / 1000.0f;
            m_timeLastUpdate = MyMinerGame.TotalGamePlayTimeInMilliseconds;

            if((MyGuiScreenGamePlay.Static.IsEditorActive() && !MyGuiScreenGamePlay.Static.IsIngameEditorActive()) || MyMinerGame.IsPaused())
                return;

            m_deltaTime += dT;

            float traveledDistance = m_speed * m_deltaTime;

            //  If sun wind finished its way, we will turn it off
            if (traveledDistance >= MySunWindConstants.SUN_WIND_LENGTH_TOTAL)
            {
                IsActive = false;
                StopCue();
                return;
            }

            Vector3 campos = MyCamera.Position;

            //  This is plane that goes through sun wind, it's in its middle
            m_planeMiddle = new MyPlane(m_initialSunWindPosition + m_directionFromSunNormalized * traveledDistance, m_directionFromSunNormalized);
            m_distanceToSunWind = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeMiddle);

            //  We make sure that sound moves always on line that goes through camera. So it's not in the middle of sun wind, more like middle where is camera.
            //  Reason is that I want the sound always go through camera.            
            m_positionOnCameraLine = MyCamera.Position - m_directionFromSunNormalized * m_distanceToSunWind;

            Vector3 positionFront = m_positionOnCameraLine + m_directionFromSunNormalized * 5000;
            Vector3 positionBack = m_positionOnCameraLine + m_directionFromSunNormalized * -5000;

            m_planeFront = new MyPlane(ref positionFront, ref m_directionFromSunNormalized);
            m_planeBack = new MyPlane(ref positionBack, ref m_directionFromSunNormalized);

            float distanceToFrontPlane = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeFront);
            float distanceToBackPlane = MyUtils.GetDistanceFromPointToPlane(ref campos, ref m_planeBack);


            Vector3 positionOfSound;
            if ((distanceToFrontPlane <= 0) && (distanceToBackPlane >= 0))
            {
                positionOfSound = MyCamera.Position;
            }
            else if (distanceToFrontPlane > 0)
            {
                positionOfSound = positionFront;
            }
            else
            {
                positionOfSound = positionBack;
            }

            //  Update position of sound. It works like this: we hear coming sound, then we are in the sound and then we hear it coming out.
            MyAudio.UpdateCuePosition(m_burningCue, positionOfSound, m_directionFromSunNormalized, -m_downVector, m_directionFromSunNormalized * m_speed);
            //MySounds.UpdateCuePosition(m_burningCue, positionOfSound, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero);

            //MyLogManager.WriteLine("positionOfSound: " + MyUtils.GetFormatedVector3(positionOfSound, 3));
            //MyLogManager.WriteLine("m_directionFromSunNormalized: " + MyUtils.GetFormatedVector3(m_directionFromSunNormalized, 3));
            //MyLogManager.WriteLine("m_downVector: " + MyUtils.GetFormatedVector3(m_downVector, 3));

            Position = positionOfSound;

            //  Shake player's head
            float distanceToSound;
            Vector3.Distance(ref positionOfSound, ref campos, out distanceToSound);
            float shake = 1 - MathHelper.Clamp(distanceToSound / 1000, 0, 1);
            if (MySession.PlayerShip != null)
            {
                MySession.PlayerShip.IncreaseHeadShake(
                    MathHelper.Lerp(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MIN,
                                    MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MAX, shake));
            }

            for (int i = 0; i < m_sunwindEntities.Count;)
			{
                if (m_sunwindEntities[i].Closed)
                {
                    m_sunwindEntities.RemoveAtFast(i);
                }
                else
                {
                    i++;
                }
            }

            //  Apply force to all objects that aren't static and are hit by sun wind (ignoring voxels and large ships)
            MyEntities.ApplySunWindForce(m_sunwindEntities, ref m_planeFront, ref m_planeBack, DoNotIgnoreTheseTypes, ref m_directionFromSunNormalized);

            //  Start small billboards
            if (m_distanceToSunWind <= MySunWindConstants.SWITCH_LARGE_AND_SMALL_BILLBOARD_DISTANCE)
            {
                Debug.Assert(m_computedMaxDistances == MySunWindConstants.SMALL_BILLBOARDS_SIZE.X * MySunWindConstants.SMALL_BILLBOARDS_SIZE.Y, "Not all small billboard MaxDistances are computed!");
                m_smallBillboardsStarted = true;
            }

            ComputeMaxDistances();
        }
Beispiel #9
0
        // It creates the MyPlane passing through a given MyVertex and parallel to a given MyPlane    ------------>>>>>>> AL MOMENTO NON SERVE!
        public static MyPlane PlaneParallelToAPlaneAndPassingThroughAPoint(MyVertex givenPoint, MyPlane givenPlane)
        {
            double[] outputNormal             = { givenPlane.a, givenPlane.b, givenPlane.c };
            double[] outputPointOfApplication = { givenPoint.x, givenPoint.y, givenPoint.z };
            var      outputPlane = new MyPlane(outputNormal, outputPointOfApplication);

            return(outputPlane);
        }
        private bool DoOverlapBoxTriangleTest(MyBox oldBox, MyBox newBox, MyTriangle_Vertex_Normal triangle, MyPlane plane, float collTolerance,
                                              ref Matrix transformMatrix, ref Vector3 oldBoxPos, ref Vector3 newBoxPos, List <MyCollisionPointStruct> collPoints)
        {
            Matrix dirs0 = newBox.Orientation;

            dirs0.Translation = Vector3.Zero;

            #region Triangle
            Vector3 triVec0 = triangle.Vertexes.Vertex0;
            Vector3 triVec1 = triangle.Vertexes.Vertex1;
            Vector3 triVec2 = triangle.Vertexes.Vertex2;
            //mesh.GetVertex(triangle.GetVertexIndex(0), out triVec0);
            //mesh.GetVertex(triangle.GetVertexIndex(1), out triVec1);
            //mesh.GetVertex(triangle.GetVertexIndex(2), out triVec2);

            // Deano move tri into world space
            //Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            MyTriangle tri = new MyTriangle(ref triVec0, ref triVec1, ref triVec2);
            #endregion


            #region triEdge0
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region triEdge1
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region triEdge2
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion


            if (triEdge0.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge1.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge2.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }


            /*
             * triEdge0 = MyMwcUtils.Normalize(triEdge0);
             * triEdge1 = MyMwcUtils.Normalize(triEdge1);
             * triEdge2 = MyMwcUtils.Normalize(triEdge2);
             */
            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            //Vector3 triNormal = triangle.Plane.Normal;
            Vector3 triNormal = plane.Normal;
            Vector3.TransformNormal(ref triNormal, ref transformMatrix, out triNormal);



            // the 15 potential separating axes (comment by Marek Rosa: note says 15 but code uses 13... I don't know why, mistake in the note??)
            const int        NUM_AXES = 13;
            MyVector3Array13 axes     = new MyVector3Array13();

            axes[0]  = triNormal;
            axes[1]  = dirs0.Right;
            axes[2]  = dirs0.Up;
            axes[3]  = dirs0.Backward;
            axes[4]  = Vector3.Cross(axes[1], triEdge0);
            axes[5]  = Vector3.Cross(axes[1], triEdge1);
            axes[6]  = Vector3.Cross(axes[1], triEdge2);
            axes[7]  = Vector3.Cross(axes[2], triEdge0);
            axes[8]  = Vector3.Cross(axes[2], triEdge1);
            axes[9]  = Vector3.Cross(axes[2], triEdge2);
            axes[10] = Vector3.Cross(axes[3], triEdge0);
            axes[11] = Vector3.Cross(axes[3], triEdge1);
            axes[12] = Vector3.Cross(axes[3], triEdge2);

            // the overlap depths along each axis
            MyFloatArray13 overlapDepths = new MyFloatArray13();

            // see if the boxes are separate along any axis, and if not keep a
            // record of the depths along each axis
            int i;
            for (i = 0; i < NUM_AXES; ++i)
            {
                overlapDepths[i] = 1.0f;

                bool b;
                overlapDepths[i] = Disjoint(out b, axes[i], newBox, tri, collTolerance);
                if (b)
                {
                    return(false);
                }
            }

            // The box overlap, find the separation depth closest to 0.
            float minDepth = float.MaxValue;
            int   minAxis  = -1;

            for (i = 0; i < NUM_AXES; ++i)
            {
                // If we can't normalise the axis, skip it
                float l2 = axes[i].LengthSquared();
                if (l2 < MyPhysicsConfig.Epsilon)
                {
                    continue;
                }

                // Normalise the separation axis and the depth
                float invl = 1.0f / (float)System.Math.Sqrt(l2);
                axes[i]          *= invl;
                overlapDepths[i] *= invl;

                // If this axis is the minimum, select it
                if (overlapDepths[i] < minDepth)
                {
                    minDepth = overlapDepths[i];
                    minAxis  = i;
                }
            }

            if (minAxis == -1)
            {
                return(false);
            }


            // Make sure the axis is facing towards the 0th box.
            // if not, invert it
            Vector3 D     = newBox.GetCentre() - tri.Centre;
            Vector3 N     = axes[minAxis];
            float   depth = overlapDepths[minAxis];

            if (Vector3.Dot(D, N) > 0.0f)
            {
                N *= -1;
            }

            Vector3 boxOldPos = oldBoxPos;                   //(info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = newBoxPos;                   // (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos   = transformMatrix.Translation; // (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            m_pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(m_pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region delta
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region oldDepth
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion


            // report collisions

            int numPts = m_pts.Count;
            if (numPts > 0)
            {
                for (i = 0; i < numPts; ++i)
                {
                    collPoints.Add(new MyCollisionPointStruct(-oldDepth, new MySmallCollPointInfo(m_pts[i] - boxNewPos, m_pts[i] - meshPos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, N, -oldDepth, m_pts[i])));
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
        protected override bool Interact(bool staticCollision)
        {
            try
            {
                if (!staticCollision)
                {
                    TestsCount++;
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("BoxTriangleIntersection");
                }

                if (RBElement1.GetElementType() != MyRBElementType.ET_BOX)
                {
                    SwapElements();
                }

                var boxElement       = (MyRBBoxElement)RBElement1;
                var triangleMeshElem = (MyRBTriangleMeshElement)RBElement2;

                MyModel model = ((boxElement.Flags & MyElementFlag.EF_MODEL_PREFER_LOD0) > 0 ? triangleMeshElem.ModelLOD0 : triangleMeshElem.Model);

                Matrix boxMatrix          = boxElement.GetGlobalTransformation();
                Matrix triangleMeshMatrix = triangleMeshElem.GetGlobalTransformation();

                Matrix newMatrix = boxMatrix;

                if (!staticCollision)
                {
                    // MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep
                    newMatrix.Translation = newMatrix.Translation + boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                }

                MyBox oldBox = m_tempBox1;
                MyBox newBox = m_tempBox2;

                oldBox.Transform.Orientation             = boxMatrix;
                oldBox.Transform.Orientation.Translation = Vector3.Zero;
                oldBox.Transform.Position = boxMatrix.Translation - Vector3.TransformNormal(boxElement.Size * 0.5f, boxMatrix);

                newBox.Transform.Orientation             = newMatrix;
                newBox.Transform.Orientation.Translation = Vector3.Zero;
                newBox.Transform.Position = newMatrix.Translation - Vector3.TransformNormal(boxElement.Size * 0.5f, newMatrix);

                oldBox.SideLengths = boxElement.Size;
                newBox.SideLengths = boxElement.Size;

                float boxRadius = newBox.GetBoundingRadiusAroundCentre();

                #region REFERENCE: Vector3 boxCentre = newBox.GetCentre();
                Vector3 boxCentre;
                newBox.GetCentre(out boxCentre);
                // Deano need to trasnform the box center into mesh space
                Matrix invTransformMatrix = Matrix.Invert(triangleMeshMatrix);

                Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);
                #endregion

                BoundingBox bb = boxElement.GetWorldSpaceAABB();

                if (staticCollision)
                {
                    Vector3 bbMin = Vector3.Transform(bb.Min, invTransformMatrix);
                    Vector3 bbMax = Vector3.Transform(bb.Max, invTransformMatrix);

                    BoundingSphere bs = new BoundingSphere((bbMax + bbMin) / 2, Vector3.Distance(bbMin, bbMax));
                    List <MyTriangle_Vertex_Normal> triangles = MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().GetFreeTriangleList(this);
                    model.GetTrianglePruningStructure().GetTrianglesIntersectingSphere(ref bs, triangles, triangles.Capacity);

                    for (int iTriangle = 0; iTriangle < triangles.Count; iTriangle++)
                    {
                        MyTriangle_Vertex_Normal triangle = triangles[iTriangle];

                        MyPlane plane = new MyPlane(ref triangle.Vertexes);

                        // quick early test is done in mesh space
                        float dist = MyUtils.GetDistanceFromPointToPlane(ref boxCentre, ref plane);

                        if (dist > boxRadius || dist < -boxRadius)
                        {
                            continue;
                        }

                        Vector3 oldPos           = boxMatrix.Translation;
                        Vector3 newPos           = newMatrix.Translation;
                        float   collisionEpsilon = 0;//pz to test not sure about value

                        if (DoOverlapBoxTriangleStaticTest(
                                oldBox, newBox,
                                triangle,
                                plane,
                                collisionEpsilon,
                                ref triangleMeshMatrix,
                                ref oldPos,
                                ref newPos))
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                else
                {
                    bb.Min += boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                    bb.Max += boxElement.GetRigidBody().LinearVelocity *MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;

                    var boxCenter = bb.GetCenter();
                    // aabox is done in mesh space and handles the mesh transform correctly
                    //int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                    //boxElement.GetRigidBody().Position = Vector3.Zero;
                    //triangleMeshElem.GetRigidBody().Position = Vector3.Zero;
                    //BoundingSphere bs = new BoundingSphere((bbMax + bbMin) / 2, Vector3.Distance(bbMin, bbMax));

                    var         halfSize = bb.Size() / 2;
                    BoundingBox bb2      = new BoundingBox(boxCentre - halfSize, boxCentre + halfSize);

                    List <MyTriangle_Vertex_Normal> triangles = MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().GetFreeTriangleList(this);

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PruningStructure");

                    model.GetTrianglePruningStructure().GetTrianglesIntersectingAABB(ref bb2, triangles, triangles.Capacity);
                    //model.GetTrianglePruningStructure().GetTrianglesIntersectingSphere(ref bs, triangles, triangles.Capacity);
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().ProfileCustomValue("Tests count ", TestsCount);

                    MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc();
                    int refPointer = 0;

                    m_collPoints.Clear();

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Triangles");

                    for (int iTriangle = 0; iTriangle < triangles.Count; iTriangle++)
                    {
                        MyTriangle_Vertex_Normal triangle = triangles[iTriangle];
                        //IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);

                        MyPlane plane = new MyPlane(ref triangle.Vertexes);

                        // quick early test is done in mesh space
                        //float dist = meshTriangle.Plane.DotCoordinate(boxCentre);
                        float dist = MyUtils.GetDistanceFromPointToPlane(ref boxCentre, ref plane);

                        if (dist > boxRadius || dist < -boxRadius)
                        {
                            continue;
                        }

                        Vector3 oldPos = boxMatrix.Translation;
                        Vector3 newPos = newMatrix.Translation;

                        DoOverlapBoxTriangleTest(
                            oldBox, newBox,
                            triangle,
                            plane,
                            MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon,
                            ref triangleMeshMatrix,
                            ref oldPos,
                            ref newPos,
                            m_collPoints);
                    }

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                    TrianglesTested += triangles.Count;

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().ProfileCustomValue("Triangles tested ", TrianglesTested);

                    m_collPoints.Sort(m_colPointComparer);

                    refPointer = 0;
                    foreach (MyCollisionPointStruct collPoint in m_collPoints)
                    {
                        collPtArray[refPointer] = collPoint.CollPointInfo;
                        refPointer++;
                        if (refPointer >= MyPhysicsConfig.MaxContactPoints)
                        {
                            break;
                        }
                    }

                    if (refPointer > 0)
                    {
                        MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, refPointer);
                    }


                    MyContactInfoCache.FreeStackAlloc(collPtArray);
                    MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().PushBackTriangleList(triangles);
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (!staticCollision)
                {
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }
            }
            return(false);
        }
        private bool DoOverlapBoxTriangleStaticTest(MyBox oldBox, MyBox newBox,
                                                    MyTriangle_Vertex_Normal triangle, MyPlane plane, float collTolerance,
                                                    ref Matrix transformMatrix, ref Vector3 oldBoxPos, ref Vector3 newBoxPos)
        {
            Matrix dirs0 = newBox.Orientation;

            dirs0.Translation = Vector3.Zero;

            #region REFERENCE: Triangle tri = new Triangle(mesh.GetVertex(triangleVertexes.GetVertexIndex(0)),mesh.GetVertex(triangleVertexes.GetVertexIndex(1)),mesh.GetVertex(triangleVertexes.GetVertexIndex(2)));
            Vector3 triVec0 = triangle.Vertexes.Vertex0;
            Vector3 triVec1 = triangle.Vertexes.Vertex1;
            Vector3 triVec2 = triangle.Vertexes.Vertex2;

            // Deano move tri into world space
            //Matrix transformMatrix = mesh.TransformMatrix;
            Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
            Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
            Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

            MyTriangle tri = new MyTriangle(ref triVec0, ref triVec1, ref triVec2);
            #endregion

            #region REFERENCE Vector3 triEdge0 = (tri.GetPoint(1) - tri.GetPoint(0));
            Vector3 pt0;
            Vector3 pt1;
            tri.GetPoint(0, out pt0);
            tri.GetPoint(1, out pt1);

            Vector3 triEdge0;
            Vector3.Subtract(ref pt1, ref pt0, out triEdge0);
            #endregion

            #region REFERENCE Vector3 triEdge1 = (tri.GetPoint(2) - tri.GetPoint(1));
            Vector3 pt2;
            tri.GetPoint(2, out pt2);

            Vector3 triEdge1;
            Vector3.Subtract(ref pt2, ref pt1, out triEdge1);
            #endregion

            #region REFERENCE Vector3 triEdge2 = (tri.GetPoint(0) - tri.GetPoint(2));
            Vector3 triEdge2;
            Vector3.Subtract(ref pt0, ref pt2, out triEdge2);
            #endregion

            if (triEdge0.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge1.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }
            if (triEdge2.LengthSquared() < MyMwcMathConstants.EPSILON)
            {
                return(false);
            }

            triEdge0.Normalize();
            triEdge1.Normalize();
            triEdge2.Normalize();

            //Vector3 triNormal = triangle.Plane.Normal;
            Vector3 triNormal = plane.Normal;
            Vector3.TransformNormal(ref triNormal, ref transformMatrix, out triNormal);

            // the 15 potential separating axes
            const int numAxes = 13;
            Vector3[] axes    = new Vector3[numAxes];

            axes[0] = triNormal;
            axes[1] = dirs0.Right;
            axes[2] = dirs0.Up;
            axes[3] = dirs0.Backward;
            Vector3.Cross(ref axes[1], ref triEdge0, out axes[4]);
            Vector3.Cross(ref axes[1], ref triEdge1, out axes[5]);
            Vector3.Cross(ref axes[1], ref triEdge2, out axes[6]);
            Vector3.Cross(ref axes[2], ref triEdge0, out axes[7]);
            Vector3.Cross(ref axes[2], ref triEdge1, out axes[8]);
            Vector3.Cross(ref axes[2], ref triEdge2, out axes[9]);
            Vector3.Cross(ref axes[3], ref triEdge0, out axes[10]);
            Vector3.Cross(ref axes[3], ref triEdge1, out axes[11]);
            Vector3.Cross(ref axes[3], ref triEdge2, out axes[12]);

            // the overlap depths along each axis
            float[] overlapDepths = new float[numAxes];

            // see if the boxes are separate along any axis, and if not keep a
            // record of the depths along each axis
            int i;
            for (i = 0; i < numAxes; ++i)
            {
                overlapDepths[i] = 1.0f;
                if (Disjoint(out overlapDepths[i], axes[i], newBox, tri, collTolerance))
                {
                    return(false);
                }
            }

            // The box overlap, find the separation depth closest to 0.
            float minDepth = float.MaxValue;
            int   minAxis  = -1;

            for (i = 0; i < numAxes; ++i)
            {
                // If we can't normalise the axis, skip it
                float l2 = axes[i].LengthSquared();
                if (l2 < MyPhysicsConfig.Epsilon)
                {
                    continue;
                }

                // Normalise the separation axis and the depth
                float invl = 1.0f / (float)System.Math.Sqrt(l2);
                axes[i]          *= invl;
                overlapDepths[i] *= invl;

                // If this axis is the minimum, select it
                if (overlapDepths[i] < minDepth)
                {
                    minDepth = overlapDepths[i];
                    minAxis  = i;
                }
            }

            if (minAxis == -1)
            {
                return(false);
            }

            // Make sure the axis is facing towards the 0th box.
            // if not, invert it
            Vector3 D     = newBox.GetCentre() - tri.Centre;
            Vector3 N     = axes[minAxis];
            float   depth = overlapDepths[minAxis];

            if (Vector3.Dot(D, N) > 0.0f)
            {
                N *= -1;
            }

            Vector3 boxOldPos = oldBoxPos;                   //(info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 boxNewPos = newBoxPos;                   // (info.Skin0.Owner != null) ? info.Skin0.Owner.Position : Vector3.Zero;
            Vector3 meshPos   = transformMatrix.Translation; // (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            List <Vector3> pts = new List <Vector3>();
            //pts.Clear();

            const float combinationDist = 0.05f;
            GetBoxTriangleIntersectionPoints(pts, newBox, tri, depth + combinationDist);

            // adjust the depth
            #region delta
            Vector3 delta;
            Vector3.Subtract(ref boxNewPos, ref boxOldPos, out delta);
            #endregion

            #region oldDepth
            float oldDepth;
            Vector3.Dot(ref delta, ref N, out oldDepth);
            oldDepth += depth;
            #endregion

            // report collisions
            int numPts = pts.Count;

            if (numPts > 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #13
0
        public void Add(MyTriangle_Vertexes triangle, Vector3 normal, ref MyPlane rightPlane, ref MyPlane upPlane, float decalScale, float alpha, bool alphaBlendByAngle, ref BoundingSphere decalSphere)
        {
            float alpha0 = alpha;
            float alpha1 = alpha;
            float alpha2 = alpha;

            if (alphaBlendByAngle == true)
            {
                alpha0 *= GetAlphaByDistance(ref triangle.Vertex0, ref decalSphere);
                alpha1 *= GetAlphaByDistance(ref triangle.Vertex1, ref decalSphere);
                alpha2 *= GetAlphaByDistance(ref triangle.Vertex2, ref decalSphere);
            }

            if ((alpha0 <= 0.0f) && (alpha1 <= 0.0f) && (alpha2 <= 0.0f))
            {
                //  Decal would be totaly transparent so it doesn't make sense to draw it
                return;
            }

            MyCockpitGlassDecalTriangle decalTriangle = m_triangles.Allocate();

            if (decalTriangle == null)
            {
                return;
            }

            decalTriangle.Position0 = triangle.Vertex0;
            decalTriangle.Position1 = triangle.Vertex1;
            decalTriangle.Position2 = triangle.Vertex2;

            //  Texture coords
            decalTriangle.TexCoord0 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref upPlane));
            decalTriangle.TexCoord1 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref upPlane));
            decalTriangle.TexCoord2 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref upPlane));

            //  Normal
            normal = MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.Normalize(normal);
            decalTriangle.Normal0 = normal;
            decalTriangle.Normal1 = normal;
            decalTriangle.Normal2 = normal;

            decalTriangle.Alpha012.X = alpha0;
            decalTriangle.Alpha012.Y = alpha1;
            decalTriangle.Alpha012.Z = alpha2;

            //  Time created
            decalTriangle.CreatedTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;
        }
        /****************************************************************************************************/
        /*    Parte aggiunta per permettere il riconoscimento di ripetizioni con la stessa origine (Katia)  */
        /****************************************************************************************************/

        public static void GetRepeatedEntities(List <List <object> > RepeatedEntities, bool EntirePart,
                                               List <MyGroupingSurface> listOfInitialGroupingSurface, SldWorks swApp)
        {
            const string fileNameBuildRepeatedEntity = "buildRepeatedEntity.txt";
            string       whatToWrite = "";

            var listOfMyRepeatedEntity = new List <MyRepeatedEntity>();
            var listOfGroupingSurfaces = new List <MyGroupingSurface>();

            if (!EntirePart)
            {
                foreach (List <object> selectedEntities in RepeatedEntities)
                {
                    //whatToWrite = string.Format("NEW SELECTED ENTITY: ");
                    //KLdebug.Print(whatToWrite, fileNameBuildRepeatedEntity);

                    var idNewRepeatedEntity            = RepeatedEntities.IndexOf(selectedEntities);
                    MyRepeatedEntity newRepeatedEntity = ExtractInfoFromBRep.BuildRepeatedEntity(
                        selectedEntities, idNewRepeatedEntity, swApp);


                    ExtractInfoFromBRep.GetSurfacesOfFacesAdjacentToSetOfFaces(
                        newRepeatedEntity, ref listOfGroupingSurfaces, swApp);

                    //GeometryAnalysis.AddFacesInformationToMyRE(newRepeatedEntity, SwApplication);
                    listOfMyRepeatedEntity.Add(newRepeatedEntity);
                }
            }
            else
            {
                /*
                 * // Parte aggiunta da Katia per il conto delle parti ripetute.
                 * if (RepeatedEntities.Count >= 3)
                 * {
                 *  foreach (var entity in RepeatedEntities)
                 *  {
                 *      var faceEntity = new List<Face2>();
                 *      foreach (var obj in entity)
                 *      {
                 *          var face = (Face2)obj;
                 *          faceEntity.Add(face);
                 *      }
                 *
                 *      //var colorParam = 1 / (RepeatedEntities.IndexOf(entity) + 0.01);
                 *      //ColorFace.KLColorFace(faceEntity, swApp, colorParam);
                 *
                 *      MyRepeatedEntity repeatedEntity = ExtractInfoFromBRep.BuildRepeatedEntity(
                 *          entity, RepeatedEntities.IndexOf(entity));
                 *      listOfMyRepeatedEntity.Add(repeatedEntity);
                 *
                 *      //var print = string.Format("Baricentro calcolato per entità {0}: {1}, {2}, {3}", RepeatedEntities.IndexOf(entity), repeatedEntity1.centroid.x,
                 *        //  repeatedEntity1.centroid.y, repeatedEntity1.centroid.z);
                 *      //swApp.SendMsgToUser(print);
                 *  }
                 *      var firstCentroid = listOfMyRepeatedEntity[0].centroid;
                 *      var secondCentroid = listOfMyRepeatedEntity[1].centroid;
                 *      var thirdCentroid = listOfMyRepeatedEntity[2].centroid;
                 *
                 *      var groupingPlane = FunctionsLC.PlanePassingThrough(firstCentroid, secondCentroid, thirdCentroid);
                 *      var groupingSurface = new MyGroupingSurface(groupingPlane, listOfMyRepeatedEntity);
                 *      listOfGroupingSurfaces.Add(groupingSurface);
                 *
                 *  string whatToWritekl =
                 *      string.Format(
                 *          "Numero delle grouping surface create da katia: {0} \nnumero entità ripetute: {1}",
                 *          listOfGroupingSurfaces.Count, RepeatedEntities.Count);
                 *  KLdebug.Print(whatToWritekl, fileNameBuildRepeatedEntity);
                 *  KLdebug.Print(" ", fileNameBuildRepeatedEntity);
                 *
                 * }
                 * */
            }


            listOfInitialGroupingSurface = listOfGroupingSurfaces;

            //SwModel = (ModelDoc2)SwApplication.ActiveDoc;
            //SwModel.ClearSelection2(true);
            //SwModel.Insert3DSketch();


            //foreach (var re in listOfMyRepeatedEntity)
            //{
            //    SwModel.CreatePoint2(re.centroid.x, re.centroid.y, re.centroid.z);
            //}
            //SwModel.InsertSketch();



            #region stampa delle MyGroupingSurface trovate nelle varie MyRepeatedEntity

            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            //KLdebug.Print("LISTA DELLE GROUPING SURFACE TROVATE:", fileNameBuildRepeatedEntity);
            //string whatToWrite1 = string.Format("Numero delle grouping surface trovate: " + listOfGroupingSurfaces.Count);
            //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            foreach (var myGroupingSurface in listOfGroupingSurfaces)
            {
                MyPlane firstPlane1;

                if (!myGroupingSurface.EntirePartAsRE)
                {
                    var thisSurface = myGroupingSurface.groupingSurface;

                    var      firstPlaneParameters1 = thisSurface.PlaneParams;
                    double[] firstPlanePoint1      =
                    {
                        firstPlaneParameters1[3], firstPlaneParameters1[4],
                        firstPlaneParameters1[5]
                    };
                    double[] firstPlaneNormal1 =
                    {
                        firstPlaneParameters1[0], firstPlaneParameters1[1],
                        firstPlaneParameters1[2]
                    };

                    //  QUAL ERA PIù IL PROBLEMA DELLE NORMALI DELLE FACCE??????
                    //  Forse vanno aggiustate le normali come ho fatto per le superfici prese da altre facce!
                    //  (vedi esempio quaderno, da' normale sbagliata di una dell superfici trovate)
                    firstPlane1 = new MyPlane(firstPlaneNormal1, firstPlanePoint1);
                }
                else
                {
                    firstPlane1 = new MyPlane(myGroupingSurface.KLplanareSurface.a, myGroupingSurface.KLplanareSurface.b,
                                              myGroupingSurface.KLplanareSurface.c, myGroupingSurface.KLplanareSurface.d);
                }

                //KLdebug.Print("Superficie:", fileNameBuildRepeatedEntity);
                //whatToWrite1 = string.Format("a {0}, b {1}, c {2}, d {3}", firstPlane1.a, firstPlane1.b, firstPlane1.c,
                //    firstPlane1.d);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //whatToWrite1 =
                //    string.Format("Numero di MyRepeatedEntity adiacenti: " + myGroupingSurface.listOfREOfGS.Count);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //KLdebug.Print(" ", "buildRepeatedEntity.txt");
            }

            #endregion



            //I remove all the MyGroupingSurface with only one occurrence
            listOfGroupingSurfaces.RemoveAll(groupingSurface => groupingSurface.listOfREOfGS.Count == 1);
            #region stampa delle MyGroupingSurface dopo la rimozione di quelle con solo una occorrenza

            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            //KLdebug.Print("LISTA DELLE GROUPING SURFACE DOPO LA RIMOZIONE DI QUELLE CON SOLO UNA 1 OCCORRENZA:", fileNameBuildRepeatedEntity);
            //whatToWrite1 = string.Format("Numero delle grouping surface trovate: " + listOfGroupingSurfaces.Count);
            //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            foreach (var myGroupingSurface in listOfGroupingSurfaces)
            {
                MyPlane firstPlane1;
                if (!EntirePart)
                {
                    var thisSurface = myGroupingSurface.groupingSurface;

                    var      firstPlaneParameters1 = thisSurface.PlaneParams;
                    double[] firstPlanePoint1      =
                    {
                        firstPlaneParameters1[3], firstPlaneParameters1[4],
                        firstPlaneParameters1[5]
                    };
                    double[] firstPlaneNormal1 =
                    {
                        firstPlaneParameters1[0], firstPlaneParameters1[1],
                        firstPlaneParameters1[2]
                    };

                    firstPlane1 = new MyPlane(firstPlaneNormal1, firstPlanePoint1);
                }
                else
                {
                    firstPlane1 = myGroupingSurface.KLplanareSurface;
                }


                //KLdebug.Print("Superficie:", fileNameBuildRepeatedEntity);
                //whatToWrite1 = string.Format("a {0}, b {1}, c {2}, d {3}", firstPlane1.a, firstPlane1.b, firstPlane1.c, firstPlane1.d);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //whatToWrite1 = string.Format("Numero di MyRepeatedEntity adiacenti: " + myGroupingSurface.listOfREOfGS.Count);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //KLdebug.Print(" ", "buildRepeatedEntity.txt");
            }

            #endregion

            //I order the list by decreasing ordering respect to number of elements of listOfREOfGS
            listOfGroupingSurfaces = listOfGroupingSurfaces.OrderByDescending(
                groupingSurface => groupingSurface.listOfREOfGS.Count).ToList();
            #region stampa delle MyGroupingSurface dopo il riordino per numero di occorrenze

            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            //KLdebug.Print("LISTA DELLE GROUPING SURFACE DOPO IL RIORDINO:", fileNameBuildRepeatedEntity);
            //whatToWrite1 = string.Format("Numero delle grouping surface trovate: " + listOfGroupingSurfaces.Count);
            //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
            //KLdebug.Print(" ", fileNameBuildRepeatedEntity);

            foreach (var myGroupingSurface in listOfGroupingSurfaces)
            {
                MyPlane firstPlane1;
                if (!EntirePart)
                {
                    var thisSurface = myGroupingSurface.groupingSurface;

                    var      firstPlaneParameters1 = thisSurface.PlaneParams;
                    double[] firstPlanePoint1      =
                    {
                        firstPlaneParameters1[3], firstPlaneParameters1[4],
                        firstPlaneParameters1[5]
                    };
                    double[] firstPlaneNormal1 =
                    {
                        firstPlaneParameters1[0], firstPlaneParameters1[1],
                        firstPlaneParameters1[2]
                    };

                    firstPlane1 = new MyPlane(firstPlaneNormal1, firstPlanePoint1);
                }
                else
                {
                    firstPlane1 = myGroupingSurface.KLplanareSurface;
                }

                //KLdebug.Print("Superficie:", fileNameBuildRepeatedEntity);
                //whatToWrite1 = string.Format("a {0}, b {1}, c {2}, d {3}", firstPlane1.a, firstPlane1.b, firstPlane1.c, firstPlane1.d);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //whatToWrite1 = string.Format("Numero di MyRepeatedEntity adiacenti: " + myGroupingSurface.listOfREOfGS.Count);
                //KLdebug.Print(whatToWrite1, fileNameBuildRepeatedEntity);
                //KLdebug.Print(" ", "buildRepeatedEntity.txt");
            }

            #endregion

            StringBuilder fileOutput = new StringBuilder();
            fileOutput.AppendLine("RICERCA PATH");


            GeometryAnalysis.MainPatternSearch_Part(true, ref listOfGroupingSurfaces,
                                                    listOfInitialGroupingSurface, ref fileOutput, swApp);
            #region per test
            //var listOfOutputPattern = new List<MyPattern>();     //list of output patterns found
            //var listOfOutputPatternTwo = new List<MyPattern>();  //list of output patterns of length 2 found
            //var toleranceOK = true;                          //it is TRUE if the tolerance level is OK during the paths searching, FALSE otherwise

            //var currentGroupingSurface = new MyGroupingSurface(listOfGroupingSurfaces[0].groupingSurface, listOfGroupingSurfaces[0].listOfREOfGS);
            //listOfGroupingSurfaces.RemoveAt(0);
            //fileOutput.AppendLine(" ");
            //fileOutput.AppendLine("CURRENT SURFACE OF TYPE: " + currentGroupingSurface.groupingSurface.Identity());
            //fileOutput.AppendLine("(Al momento sono rimaste " + listOfGroupingSurfaces.Count + " superfici, compresa questa.)");

            //var ListOfREOnThisSurface =
            //    currentGroupingSurface.listOfREOfGS.Select(myRepeatedEntity => myRepeatedEntity).ToList();
            //var listOfCentroidsThisGS =
            //    currentGroupingSurface.listOfREOfGS.Select(myRepeatedEntity => myRepeatedEntity.centroid).ToList();
            //var maxPath = false; //it is TRUE if the maximum Pattern is found, FALSE otherwise.

            //List<MyMatrAdj> listOfMyMatrAdj = Functions.CreateMatrAdj(listOfCentroidsThisGS, ref fileOutput);
            //fileOutput.AppendLine(" ----> listOfMyMatrAdj.Count = " + listOfMyMatrAdj.Count + ". Ora rimuovo la posizione 0:");

            //var currentMatrAdj = new MyMatrAdj(listOfMyMatrAdj[0].d, listOfMyMatrAdj[0].matr, listOfMyMatrAdj[0].nOccur);
            //listOfMyMatrAdj.Remove(listOfMyMatrAdj[0]);
            //fileOutput.AppendLine(" ");
            //fileOutput.AppendLine("Esamino NUOVA MatrAdj. La elimino dalla lista.");
            //fileOutput.AppendLine(" ----> aggiornato listOfMyMatrAdj.Count = " + listOfMyMatrAdj.Count);
            //fileOutput.AppendLine("AVVIO RICERCA PATH in questa MatrAdj!");
            //fileOutput.AppendLine(" ");

            //bool onlyShortPath;

            //var listOfPathOfCentroids = new List<MyPathOfPoints>();
            //maxPath = Functions.FindPaths(currentMatrAdj, ListOfREOnThisSurface, ref fileOutput,
            //    out listOfPathOfCentroids, out onlyShortPath, ref toleranceOK,
            //    ref listOfMyMatrAdj, ref listOfGroupingSurfaces,
            //    ref listOfOutputPattern,
            //    ref listOfOutputPatternTwo);

            //fileOutput.AppendLine(" ");
            //fileOutput.AppendLine("RISULTA DA QUESTA MATRADJ: ");
            //fileOutput.AppendLine("maxPath = " + maxPath);
            //fileOutput.AppendLine("listOfMyPattern.Count = " + listOfOutputPattern.Count);
            //fileOutput.AppendLine("listOfMyPatternTwo.Count = " + listOfOutputPatternTwo.Count);
            //fileOutput.AppendLine("onlyShortPath = " + onlyShortPath);
            //fileOutput.AppendLine("toleranceOK = " + toleranceOK);
            //fileOutput.AppendLine("listOfPathOfCentroids.Count = " + listOfPathOfCentroids.Count);

            ////PATTERN

            //var myPathOfCentroids = listOfPathOfCentroids[0];
            //listOfPathOfCentroids.RemoveAt(0);
            //var listOfREOnThePath = myPathOfCentroids.path.Select(ind => ListOfREOnThisSurface[ind]).ToList();
            //GeometryAnalysis.GetTranslationalPatterns(listOfREOnThePath, myPathOfCentroids.pathGeometricObject,
            //    ref listOfPathOfCentroids, listOfCentroidsThisGS,
            //    ref listOfMyMatrAdj, ref listOfGroupingSurfaces, ref listOfOutputPattern, ref listOfOutputPatternTwo);

            #endregion


            // Create a file to write to.
            string mydocpath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
            using (StreamWriter outfile = new StreamWriter(mydocpath + @"\PathCreation.txt", true))
            {
                outfile.Write(fileOutput.ToString());
                outfile.Close();
            }
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3?referenceNormalVector = null;
            float?  maxAngle = null;

            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();

            // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery"); // This code is called recursively and cause profiler to lag
            bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles);

            // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles");  // This code is called recursively and cause profiler to lag

                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        return;
                    }

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //gi_aabb.CollideTriangleExact

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                            triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                            triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normal retTriangle;
                                    retTriangle.Vertexes = triangle;
                                    retTriangle.Normal   = calculatedTriangleNormal;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
Beispiel #16
0
        internal bool Intersects(ref BoundingSphere sphere)
        {
            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBox sphereBoundingBox = BoundingBox.CreateInvalid();

            sphereBoundingBox.Include(ref sphere);
            Vector3I cellCoordMin = GetCellCoordinateFromMeters(ref sphereBoundingBox.Min);
            Vector3I cellCoordMax = GetCellCoordinateFromMeters(ref sphereBoundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            FixDataCellCoord(ref cellCoordMin);
            FixDataCellCoord(ref cellCoordMax);

            Vector3I cellCoord;

            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref sphere) == false)
                        {
                            continue;
                        }

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        CellData cachedDataCell = GetCell(MyLodTypeEnum.LOD0, ref cellCoord);

                        if (cachedDataCell == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < cachedDataCell.VoxelTrianglesCount; i++)
                        {
                            MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                            MyTriangle_Vertexes triangle;
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);
                            triangle.Vertex0 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex1 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex2 += m_voxelMap.PositionLeftBottomCorner;

                            BoundingBox voxelTriangleBoundingBox = BoundingBox.CreateInvalid();
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex0);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex1);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex2);

                            //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                            if (voxelTriangleBoundingBox.Intersects(ref sphere))
                            {
                                MyPlane trianglePlane = new MyPlane(ref triangle);

                                if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                                {
                                    //  If intersection found - we are finished. We don't need to look for more.
                                    Profiler.End();
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        //  Return true if object intersects specified sphere.
        //  This method doesn't return exact point of intersection or any additional data.
        //  We don't look for closest intersection - so we stop on first intersection found.
        //  IMPORTANT: Sphere must be in model space, so don't transform it!
        public bool GetIntersectionWithSphere(MyModel model, ref BoundingSphere sphere)
        {
            //  Check if sphere intersects bounding box of this node
            if (MyUtils.IsBoxIntersectingSphere(ref m_boundingBox, ref sphere) == false)
            {
                return false;         
            }

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertexes triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    MyPlane trianglePlane = new MyPlane(ref triangle);

                    if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                    {
                        //  If we found intersection we can stop and dont need to look further
                        return true;
                    }                    
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    if (m_childs[i].GetIntersectionWithSphere(model, ref sphere))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Beispiel #18
0
        public static bool CheckOfPlanesForReflection(MyRepeatedEntity firstMyRepeatedEntity, MyRepeatedEntity secondMyRepeatedEntity, MyPlane candidateReflMyPlane)
        {
            //const string nameFile = "GetReflectionalPattern.txt";
            //KLdebug.Print(" ", nameFile);
            //KLdebug.Print("------>> CHECK DELLE NORMALI DELLE FACCE PLANARI:", nameFile);
            //var whatToWrite = "";

            var numOfPlanarSurfacesFirst  = firstMyRepeatedEntity.listOfPlanarSurfaces.Count;
            var numOfPlanarSurfacesSecond = secondMyRepeatedEntity.listOfPlanarSurfaces.Count;

            if (numOfPlanarSurfacesFirst == numOfPlanarSurfacesSecond)
            {
                //KLdebug.Print("Numero di facce planari prima RE: " + numOfPlanarSurfacesFirst, nameFile);
                //KLdebug.Print("Numero di facce planari seconda RE: " + numOfPlanarSurfacesSecond, nameFile);
                //KLdebug.Print("Il numero di facce planari corrisponde, passo alla verifica delle normali:", nameFile);
                //KLdebug.Print(" ", nameFile);

                //If there are planar faces I check the correct position of the normals
                if (numOfPlanarSurfacesFirst > 0)
                {
                    var listOfFirstNormals  = new List <double[]>();
                    var listOfSecondNormals = new List <double[]>();

                    //KLdebug.Print("Lista delle normali delle facce planari 1^ RE:", nameFile);
                    foreach (var planarSurface in firstMyRepeatedEntity.listOfPlanarSurfaces)
                    {
                        double[] normalToAdd = { planarSurface.a, planarSurface.b, planarSurface.c };
                        listOfFirstNormals.Add(normalToAdd);

                        //whatToWrite = string.Format("-aggiunta ({0},{1},{2})", normalToAdd[0], normalToAdd[1], normalToAdd[2]);
                        //KLdebug.Print(whatToWrite, nameFile);
                    }

                    //KLdebug.Print(" ", nameFile);
                    //KLdebug.Print("Lista delle normali delle facce planari 2^ RE:", nameFile);
                    foreach (var planarSurface in secondMyRepeatedEntity.listOfPlanarSurfaces)
                    {
                        double[] normalToAdd = { planarSurface.a, planarSurface.b, planarSurface.c };
                        listOfSecondNormals.Add(normalToAdd);

                        //whatToWrite = string.Format("-aggiunta ({0},{1},{2})", normalToAdd[0], normalToAdd[1], normalToAdd[2]);
                        //KLdebug.Print(whatToWrite, nameFile);
                    }

                    //KLdebug.Print(" ", nameFile);
                    //KLdebug.Print("Inizio della verifica della corrispondenza delle normali", nameFile);
                    int i = 0;
                    while (listOfSecondNormals.Count != 0 && i < numOfPlanarSurfacesFirst)  // DOVREBBERO ESSERE FALSE O VERE CONTEMPORANEAMENTE!!!
                    {
                        //KLdebug.Print(i + "-esima normale della 1^RE:", nameFile);

                        var reflectedNormal = ReflectNormal(listOfFirstNormals[i], candidateReflMyPlane);

                        var indexOfFound =
                            listOfSecondNormals.FindIndex(normal => FunctionsLC.MyEqualsArray(normal, reflectedNormal));
                        if (indexOfFound != -1)
                        {
                            //whatToWrite = string.Format("Analizzo la normale: ({0},{1},{2})", listOfFirstNormals[i][0], listOfFirstNormals[i][1], listOfFirstNormals[i][2]);
                            //KLdebug.Print(whatToWrite, nameFile);
                            //KLdebug.Print(" -> Trovata corrispondenza con una faccia planare della 2^ RE;", nameFile);

                            listOfSecondNormals.RemoveAt(indexOfFound);
                            i++;
                        }
                        else
                        {
                            //    KLdebug.Print(" -> Non è stata trovata corrispondenza con le normali della 2^ RE.", nameFile);
                            //    KLdebug.Print("FINE", nameFile);
                            return(false);
                        }
                        // KLdebug.Print(" ", nameFile);
                    }
                    //KLdebug.Print(" ", nameFile);

                    return(true);
                }
                else
                {
                    //KLdebug.Print("NESSUNA FACCIA PLANARE.", nameFile);
                    //KLdebug.Print("FINE", nameFile);
                    return(true);
                }
            }
            else
            {
                //KLdebug.Print("NUMERO DI FACCE PLANARI NON CORRISPONDENTE", nameFile);
                //KLdebug.Print("FINE", nameFile);
                return(false);
            }
        }
        protected override bool Interact(bool staticCollision)
        {
            if (staticCollision)
            {
                //MyCommonDebugUtils.AssertDebug(false, "Sphere-voxel static interaction called! And that's wrong.");
            }
            else
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("SphereVoxelInteraction");

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Transformations");

                if (RBElement1.GetElementType() != MyRBElementType.ET_SPHERE)
                {
                    SwapElements();
                }

                Matrix matrix0 = RBElement1.GetGlobalTransformation();
                Matrix matrix1 = RBElement2.GetGlobalTransformation();

                float sphereRadius = ((MyRBSphereElement)RBElement1).Radius;

                Vector3 body0Pos = matrix0.Translation; // sphere pos
                Vector3 body1Pos = matrix1.Translation;

                float dt      = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                float epsylon = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon;

                Vector3 newBody0Pos = matrix0.Translation + GetRigidBody1().LinearVelocity *dt;

                float sphereTolR  = epsylon + sphereRadius;
                float sphereTolR2 = sphereTolR * sphereTolR;

                MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc();
                int numCollPts = 0;

                Vector3 collNormal = Vector3.Zero;

                //var colDetThroughVoxels = MyConstants.SPHERE_VOXELMAP_COLDET_THROUGH_VOXELS;
                var colDetThroughVoxels = !GetRigidBody1().ReadFlag(RigidBodyFlag.RBF_COLDET_THROUGH_VOXEL_TRIANGLES);

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                if (colDetThroughVoxels)
                {
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("colDetThroughVoxels");

                    BoundingSphere newSphere;
                    newSphere.Center = newBody0Pos;
                    newSphere.Radius = sphereRadius;

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PoolList.Get");
                    using (var voxelMapsFounded = PoolList <MyVoxelMap> .Get())
                    {
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere");

                        MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref newSphere, voxelMapsFounded, null);

                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("foreach (MyVoxelMap voxelMap in voxelMapsFounded)");
                        foreach (MyVoxelMap voxelMap in voxelMapsFounded)
                        {
                            if (voxelMap != null)
                            {
                                //  We will iterate only voxels contained in the bounding box of new sphere, so here we get min/max corned in voxel units
                                MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                                                                                                      newSphere.Center.X - newSphere.Radius,
                                                                                                      newSphere.Center.Y - newSphere.Radius,
                                                                                                      newSphere.Center.Z - newSphere.Radius));
                                MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                                                                                                      newSphere.Center.X + newSphere.Radius,
                                                                                                      newSphere.Center.Y + newSphere.Radius,
                                                                                                      newSphere.Center.Z + newSphere.Radius));
                                voxelMap.FixVoxelCoord(ref minCorner);
                                voxelMap.FixVoxelCoord(ref maxCorner);

                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("for loop");

                                MyMwcVector3Int tempVoxelCoord;
                                for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
                                {
                                    for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                                    {
                                        for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                                        {
                                            byte voxelContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                                            //  Ignore voxels bellow the ISO value (empty, partialy empty...)
                                            if (voxelContent < MyVoxelConstants.VOXEL_ISO_LEVEL)
                                            {
                                                continue;
                                            }

                                            Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);

                                            //float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF;
                                            float voxelSize = MyVoxelMaps.GetVoxelContentAsFloat(voxelContent) * MyVoxelConstants.VOXEL_RADIUS;

                                            //  If distance to voxel border is less than sphere radius, we have a collision
                                            //  So now we calculate normal vector and penetration depth but on OLD sphere
                                            float newDistanceToVoxel = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize;
                                            if (newDistanceToVoxel < (epsylon + newSphere.Radius))
                                            {
                                                Vector3 collisionN = MyMwcUtils.Normalize(voxelPosition - body0Pos);

                                                if (numCollPts < MyPhysicsConfig.MaxContactPoints)
                                                {
                                                    //  Calculate penetration depth, but from old sphere (not new)
                                                    float oldDistanceToVoxel  = Vector3.Distance(voxelPosition, newSphere.Center) - voxelSize;
                                                    float oldPenetrationDepth = oldDistanceToVoxel - sphereRadius;

                                                    // Vector3 pt = body0Pos + sphereRadius * collisionN;
                                                    Vector3 pt = voxelPosition - collisionN * (voxelSize - epsylon);

                                                    collPtArray[numCollPts++] = new MySmallCollPointInfo(pt - body0Pos, pt - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, oldPenetrationDepth, pt);
                                                }

                                                collNormal -= collisionN;
                                            }
                                        }
                                    }
                                }

                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                            }
                        }

                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                    }

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }
                else //if (colDetThroughVoxels)
                {
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ColDet triangles");

                    int optimalIterationCount = (int)(GetRigidBody1().LinearVelocity.Length() * dt / sphereRadius);
                    int maxIndex = (int)MathHelper.Min(MathHelper.Max(optimalIterationCount, 1), 16);

                    for (int i = 0; i < maxIndex; i++)
                    {
                        float velocityAdd = GetRigidBody1().LinearVelocity.Length() * dt / (float)maxIndex;

                        Vector3 interpolatedPosition = body0Pos + GetRigidBody1().LinearVelocity *dt *i / (float)maxIndex;

                        BoundingSphere newSphere;
                        newSphere.Center = interpolatedPosition;
                        newSphere.Radius = sphereRadius;

                        int numTriangles;

                        BoundingBox bb = BoundingBox.CreateFromSphere(newSphere);
                        MyVoxelMaps.GetPotentialTrianglesForColDet(out numTriangles, ref bb);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            MyColDetVoxelTriangle meshTriangle = MyVoxelMaps.PotentialColDetTriangles[iTriangle]; // mesh.GetTriangle(potentialTriangles[iTriangle]);


                            MyTriangle_Vertex_Normal triangle = new MyTriangle_Vertex_Normal();
                            triangle.Vertexes.Vertex0 = meshTriangle.Vertex0;
                            triangle.Vertexes.Vertex1 = meshTriangle.Vertex1;
                            triangle.Vertexes.Vertex2 = meshTriangle.Vertex2;


                            // skip too narrow triangles causing instability
                            if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            if ((triangle.Vertexes.Vertex1 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                            {
                                continue;
                            }

                            MyPlane plane = new MyPlane(ref triangle.Vertexes);

                            Vector3?pt = MyUtils.GetSphereTriangleIntersection(ref newSphere, ref plane, ref triangle.Vertexes);
                            if (pt == null)
                            {
                                continue;
                            }


                            Vector3 collisionN = plane.Normal;

                            // skip triangle in case the normal is in wrong dir (narrow walls)
                            Vector3 tempV = (newBody0Pos - pt.Value);
                            if (Vector3.Dot(collisionN, tempV) >= 0.8f * tempV.Length())  // equivalent to dot(collisionN, normalize(tempV)) > 0.8f, but works for zero vectors
                            {
                                continue;
                            }

                            float depth = Vector3.Distance(pt.Value, body0Pos) - sphereRadius;

                            if (numCollPts < MyPhysicsConfig.MaxContactPoints)
                            {
                                // since impulse get applied at the old position
                                Vector3 p2 = pt.Value;

                                collPtArray[numCollPts++] = new MySmallCollPointInfo(p2 - body0Pos, p2 - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, depth, p2);
                            }

                            collNormal += collisionN;
                        }
                    }

                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }

                if (numCollPts > 0)
                {
                    MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numCollPts);
                }
                MyContactInfoCache.FreeStackAlloc(collPtArray);

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            return(false);
        }
Beispiel #20
0
        public static bool CheckOfCylindersForReflection(MyRepeatedEntity firstMyRepeatedEntity, MyRepeatedEntity secondMyRepeatedEntity, MyPlane candidateReflMyPlane)
        {
            var numOfCylinderSurfacesFirst  = firstMyRepeatedEntity.listOfCylindricalSurfaces.Count;
            var numOfCylinderSurfacesSecond = secondMyRepeatedEntity.listOfCylindricalSurfaces.Count;

            if (numOfCylinderSurfacesFirst == numOfCylinderSurfacesSecond)
            {
                if (numOfCylinderSurfacesFirst > 0)
                {
                    var listOfCylindersToLookIn = new List <MyCylinder>(secondMyRepeatedEntity.listOfCylindricalSurfaces);
                    int i = 0;
                    while (listOfCylindersToLookIn.Count != 0 && i < numOfCylinderSurfacesFirst)
                    {
                        var cylinderOfFirst = firstMyRepeatedEntity.listOfCylindricalSurfaces[i];

                        if (!CylinderOfFirstAtPosition_i_IsOkReflection(firstMyRepeatedEntity, secondMyRepeatedEntity, candidateReflMyPlane, cylinderOfFirst, ref i))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
                return(true);
            }
            return(false);
        }
        public bool GetIntersectionWithSphere(MyEntity physObject, ref BoundingSphere sphere)
        {
            //  Transform sphere from world space to object space
            Matrix worldInv = physObject.GetWorldMatrixInverted();
            Vector3 positionInObjectSpace = MyUtils.GetTransform(sphere.Center, ref worldInv);
            BoundingSphere sphereInObjectSpace = new BoundingSphere(positionInObjectSpace, sphere.Radius);

            var aabb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSphere(ref sphereInObjectSpace, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);
            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                //  Triangles that are directly in this node
                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphereInObjectSpace) == true)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes triangle;
                        MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                        triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);

                        MyPlane trianglePlane = new MyPlane(ref triangle);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphereInObjectSpace, ref trianglePlane, ref triangle) != null)
                        {
                            //  If we found intersection we can stop and dont need to look further
                            return true;
                        }
                    }
                }
            }

            return false;
        }
Beispiel #22
0
        public static bool CylinderOfFirstAtPosition_i_IsOkReflection(MyRepeatedEntity firstMyRepeatedEntity,
                                                                      MyRepeatedEntity secondMyRepeatedEntity, MyPlane candidateReflMyPlane, MyCylinder cylinderOfFirst, ref int i)
        {
            const string nameFile  = "GetReflectionalPattern.txt";
            var          tolerance = Math.Pow(10, -5);

            //I compute the distance vector v between the centroidOfFirst and the Origin of the cylinderOfFirst (which pass through the axis)
            //The axis of the second MyRepeatedEntity should have the same axis direction and
            //should pass through the point = centroidOfSecond + v
            double[] originOfFirst         = cylinderOfFirst.originCylinder;
            var      originOfFirstMyVertex = new MyVertex(originOfFirst[0], originOfFirst[1], originOfFirst[2]);

            var pointOnAxisMyVertex = originOfFirstMyVertex.Reflect(candidateReflMyPlane);

            double[] pointOnAxis = { pointOnAxisMyVertex.x, pointOnAxisMyVertex.y, pointOnAxisMyVertex.z };

            var reflectedDirectionOfAxis = ReflectNormal(cylinderOfFirst.axisDirectionCylinder, candidateReflMyPlane);

            var axisToFind = FunctionsLC.ConvertPointPlusDirectionInMyLine(pointOnAxis,
                                                                           reflectedDirectionOfAxis);
            var indOfFound =
                secondMyRepeatedEntity.listOfCylindricalSurfaces.FindIndex(
                    cyl => cyl.axisCylinder.Equals(axisToFind));

            if (indOfFound != -1)
            {
                var listOfPossibleCylinders =
                    secondMyRepeatedEntity.listOfCylindricalSurfaces.FindAll(
                        cyl => cyl.axisCylinder.Equals(axisToFind));
                var numOfPossibleCylinders = listOfPossibleCylinders.Count;

                //If I find cylinders with right axis line, I check the radius correspondence,
                //the center of bases correspondence.
                //For elliptical bases I make a further control on radius and direction axis.
                var notFound = true;
                int j        = 0;
                while (notFound && j < numOfPossibleCylinders)
                {
                    var possibleCylinder = listOfPossibleCylinders[j];
                    if (Math.Abs(cylinderOfFirst.radiusCylinder - possibleCylinder.radiusCylinder) < tolerance)
                    {
                        if (CheckOfClosedEdgesCorrespondenceRefl(cylinderOfFirst, possibleCylinder,
                                                                 candidateReflMyPlane))
                        {
                            notFound = false;
                        }
                    }
                    j++;
                }
                if (notFound)
                {
                    return(false);
                }

                //if the previous cylinder is ok, i pass to the next cylinder:
                i++;
            }
            else
            {
                return(false);
            }
            return(true);
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, Vector3? referenceNormalVector, float? maxAngle, List<MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var aabb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);
            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles) return;

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals triangleNormals;
                            MyTriangle_Normals triangleBinormals;
                            MyTriangle_Normals triangleTangents;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

                            /*
                            triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                            triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                            triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                              */

                            triangleNormals.Normal0 = m_model.GetVertexNormal(triangleIndices.I0);
                            triangleNormals.Normal1 = m_model.GetVertexNormal(triangleIndices.I2);
                            triangleNormals.Normal2 = m_model.GetVertexNormal(triangleIndices.I1);

                            if (MinerWars.AppCode.Game.Render.MyRenderConstants.RenderQualityProfile.ForwardRender)
                            {
                                triangleBinormals.Normal0 = triangleNormals.Normal0;
                                triangleBinormals.Normal1 = triangleNormals.Normal1;
                                triangleBinormals.Normal2 = triangleNormals.Normal2;

                                triangleTangents.Normal0 = triangleNormals.Normal0;
                                triangleTangents.Normal1 = triangleNormals.Normal1;
                                triangleTangents.Normal2 = triangleNormals.Normal2;
                            }
                            else
                            {
                                triangleBinormals.Normal0 = m_model.GetVertexBinormal(triangleIndices.I0);
                                triangleBinormals.Normal1 = m_model.GetVertexBinormal(triangleIndices.I2);
                                triangleBinormals.Normal2 = m_model.GetVertexBinormal(triangleIndices.I1);

                                triangleTangents.Normal0 = m_model.GetVertexTangent(triangleIndices.I0);
                                triangleTangents.Normal1 = m_model.GetVertexTangent(triangleIndices.I2);
                                triangleTangents.Normal2 = m_model.GetVertexTangent(triangleIndices.I1);
                            }

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normals retTriangle;
                                    retTriangle.Vertexes = triangle;
                                    retTriangle.Normals = triangleNormals;
                                    retTriangle.Binormals = triangleBinormals;
                                    retTriangle.Tangents = triangleTangents;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #24
0
        //Given 2 cylinder with corresponding radius and axis (MyLine) corresponding to the expected position for translation,
        //given the translation vector, it returns TRUE if the two base edges corresponds to the ones of the second cylinder,
        //it return FALSE otherwise.
        //For circles: a comparison of the centers is sufficient
        //For ellipses: a comparison of the centers, of the major and minor radius and of the axis (MyLine) is necessary
        public static bool CheckOfClosedEdgesCorrespondenceRefl(MyCylinder cylinderOfFirst, MyCylinder possibleCylinder, MyPlane candidateReflMyPlane)
        {
            const string nameFile = "GetReflectionalPattern.txt";

            var listOfCircleFirst   = cylinderOfFirst.listOfBaseCircle;
            var listOfCircleSecond  = new List <MyCircle>(possibleCylinder.listOfBaseCircle);
            var listOfEllipseFirst  = cylinderOfFirst.listOfBaseEllipse;
            var listOfEllipseSecond = new List <MyEllipse>(possibleCylinder.listOfBaseEllipse);

            int numOfCircleFirst   = listOfCircleFirst.Count;
            int numOfEllipseFirst  = listOfEllipseFirst.Count;
            int numOfCircleSecond  = listOfCircleSecond.Count;
            int numOfEllipseSecond = listOfEllipseSecond.Count;

            if (numOfCircleFirst == numOfCircleSecond && numOfEllipseFirst == numOfEllipseSecond)
            {
                if (numOfCircleFirst + numOfEllipseFirst == 0)  //cylinders with baseFace not planar
                {
                    return(true);
                }
                if (!CorrespondenceOfCirclesInCylinderRefl(candidateReflMyPlane, listOfCircleFirst, listOfCircleSecond))
                {
                    return(false);
                }

                if (!CorrespondenceOfEllipsesInCylinderRefl(candidateReflMyPlane, listOfEllipseFirst, listOfEllipseSecond))
                {
                    return(false);
                }

                return(true);
            }
            return(false);
        }
Beispiel #25
0
        //  Add decal and all surounding triangles for model intersection
        static void AddDecalModel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle, 
            ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyDecalsForPhysObjectsTriangleBuffer decalsBuffer = m_decalsForModels.GetTrianglesBuffer(intersection.Entity, decalTexture);

            //  If we get null, buffer is full so no new decals can't be placed
            if (decalsBuffer == null) return;

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            BoundingSphere decalSphere = new BoundingSphere(intersection.IntersectionPointInObjectSpace, decalSize);
            m_neighbourTriangles.Clear();
            
            intersection.Entity.GetTrianglesIntersectingSphere(ref decalSphere, intersection.NormalInObjectSpace, MyDecalsConstants.MAX_NEIGHBOUR_ANGLE, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);

            int trianglesToAdd = m_neighbourTriangles.Count;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd))
            {
                Vector3 normalSum = Vector3.Zero;
                if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                {
                    normalSum = CalculateDominantNormal(m_neighbourTriangles);
                    normalSum *= decalNormalOffset;
                }

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    if (MyFakes.USE_DOMINANT_NORMAL_OFFSET_FOR_MODELS)
                    {
                        var triangle = m_neighbourTriangles[i];
                        triangle.Vertexes.Vertex0 += normalSum;
                        triangle.Vertexes.Vertex1 += normalSum;
                        triangle.Vertexes.Vertex2 += normalSum;
                        m_neighbourTriangles[i] = triangle;
                    }

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.Triangle.InputTriangleNormal,
                        ref rightPlane, ref upPlane, decalScale, decalSize, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInObjectSpace, emissivity);
                }
            }
        }
Beispiel #26
0
        public static bool CorrespondenceOfEllipsesInCylinderRefl(MyPlane candidateReflMyPlane,
                                                                  List <MyEllipse> listOfEllipseFirst, List <MyEllipse> listOfEllipseSecond)
        {
            const string nameFile = "GetReflectionalPattern.txt";

            var numOfEllipseFirst  = listOfEllipseFirst.Count;
            var numOfEllipseSecond = listOfEllipseSecond.Count;
            var tolerance          = Math.Pow(10, -5);

            // OBSERVATION: int i, j are such that 0<=i,j<=2
            if (numOfEllipseFirst > 0)
            {
                int i = 0;
                // for every ellipse of first cylinder
                while (i < numOfEllipseFirst)
                {
                    var firstEllipse    = listOfEllipseFirst[i];
                    int j               = 0;
                    var thisEllipseIsOk = false;

                    while (thisEllipseIsOk == false && j < numOfEllipseSecond)
                    {
                        var secondEllipse = listOfEllipseSecond[j];

                        //comparison of the ellipse centers:
                        thisEllipseIsOk = secondEllipse.centerEllipse.IsReflectionOf(firstEllipse.centerEllipse,
                                                                                     candidateReflMyPlane);
                        if (thisEllipseIsOk)
                        {
                            //if the radius correspond:
                            if (Math.Abs(firstEllipse.majorRadEllipse - secondEllipse.majorRadEllipse) < tolerance &&
                                Math.Abs(firstEllipse.minorRadEllipse - secondEllipse.minorRadEllipse) < tolerance)
                            {
                                //check if the directions corresponding to the axis are ok:

                                double[] firstMajorAxisDirectionEllipseOpposite =
                                {
                                    -firstEllipse.majorAxisDirectionEllipse[0],
                                    -firstEllipse.majorAxisDirectionEllipse[1],
                                    -firstEllipse.majorAxisDirectionEllipse[2]
                                };
                                double[] firstMinorAxisDirectionEllipseOpposite =
                                {
                                    -firstEllipse.minorAxisDirectionEllipse[0],
                                    -firstEllipse.minorAxisDirectionEllipse[1],
                                    -firstEllipse.minorAxisDirectionEllipse[2]
                                };
                                if (FunctionsLC.MyEqualsArray(ReflectNormal(firstEllipse.majorAxisDirectionEllipse, candidateReflMyPlane), secondEllipse.majorAxisDirectionEllipse) ||
                                    FunctionsLC.MyEqualsArray(ReflectNormal(firstMajorAxisDirectionEllipseOpposite, candidateReflMyPlane), secondEllipse.majorAxisDirectionEllipse))
                                {
                                    if (
                                        FunctionsLC.MyEqualsArray(ReflectNormal(firstEllipse.minorAxisDirectionEllipse, candidateReflMyPlane), secondEllipse.minorAxisDirectionEllipse) ||
                                        FunctionsLC.MyEqualsArray(ReflectNormal(firstMinorAxisDirectionEllipseOpposite, candidateReflMyPlane), secondEllipse.minorAxisDirectionEllipse))
                                    {
                                        listOfEllipseSecond.RemoveAt(j);
                                    }
                                    else
                                    {
                                        thisEllipseIsOk = false;
                                    }
                                }
                                else
                                {
                                    thisEllipseIsOk = false;
                                }
                            }
                            else
                            {
                                thisEllipseIsOk = false;
                            }
                        }
                        j++;
                    }
                    if (!thisEllipseIsOk)
                    {
                        return(false);
                    }
                    else
                    {
                        numOfEllipseSecond = listOfEllipseSecond.Count;
                        i++;
                    }
                }
            }

            return(true);
        }
        protected override bool Interact(bool staticCollision)
        {
            if (RBElement1.GetElementType() != MyRBElementType.ET_SPHERE)
                SwapElements();

            Matrix matrix0 = RBElement1.GetGlobalTransformation();
            Matrix matrix1 = RBElement2.GetGlobalTransformation();

            float sphereRadius = ((MyRBSphereElement)RBElement1).Radius;

            Vector3 body0Pos = matrix0.Translation; // sphere pos
            Vector3 body1Pos = matrix1.Translation;

            Matrix tempMat1 = matrix1;

            Matrix inverseMatrix1 = Matrix.Invert(tempMat1);

            MyModel model = ((RBElement1.Flags & MyElementFlag.EF_MODEL_PREFER_LOD0) > 0 ? ((MyRBTriangleMeshElement)RBElement2).ModelLOD0 : ((MyRBTriangleMeshElement)RBElement2).Model);

            if (staticCollision)
            {
                BoundingSphere bsphere = new BoundingSphere(body0Pos, sphereRadius);
                return model.GetTrianglePruningStructure().GetIntersectionWithSphere(((MinerWars.AppCode.Game.Physics.MyPhysicsBody)RBElement2.GetRigidBody().m_UserData).Entity, ref bsphere);
            }
            else
            {
                float dt = MyPhysics.physicsSystem.GetRigidBodyModule().CurrentTimeStep;
                float epsilon = MyPhysics.physicsSystem.GetRigidBodyModule().CollisionEpsilon;

                MySmallCollPointInfo[] collPtArray = MyContactInfoCache.SCPIStackAlloc();
                int numCollPts = 0;

                Vector3 collNormal = Vector3.Zero;

                int optimalIterationCount = (int)(GetRigidBody1().LinearVelocity.Length() * dt / (sphereRadius * 2)) + 1;
                //PZ: after consultation with petrM 1-4 iteration will be just ok
                int maxIndex = (int)MathHelper.Min(optimalIterationCount, MAX_AVAILABLE_ITERATION);
                //float speed = GetRigidBody1().LinearVelocity.Length();

                Vector3 velocityAdd = GetRigidBody1().LinearVelocity * dt / (float)maxIndex;
                float velocityAddLength = velocityAdd.Length();

                List<MyTriangle_Vertex_Normal> triangles = MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().GetFreeTriangleList(this);

                //PZ: we will try to interpolate sphere position during this tick
                //we have to have at least one iteration
                for (int index = 0; index < maxIndex; index++)
                {
                    //PZ: from starting point 
                    Vector3 interpolatedPosition = body0Pos + velocityAdd * index;

                    // Deano : get the spheres centers in triangleVertexes mesh space
                    Vector3 newSphereCen = Vector3.Transform(interpolatedPosition, inverseMatrix1);

                    //  Transform sphere from world space to object space                        
                    BoundingSphere newSphereInObjectSpace = new BoundingSphere(newSphereCen, sphereRadius + velocityAddLength + epsilon);
                    BoundingBox newAABBInObjectSpace = BoundingBox.CreateFromSphere(newSphereInObjectSpace);

                    model.GetTrianglePruningStructure().GetTrianglesIntersectingAABB(ref newAABBInObjectSpace, triangles, triangles.Capacity);

                    for (int i = 0; i < triangles.Count; i++)
                    {
                        MyTriangle_Vertex_Normal triangle = triangles[i];

                        // skip too narrow triangles causing instability
                        /*    This must be done in preprocessor!
                        if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex1).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                        {
                            continue;
                        }

                        if ((triangle.Vertexes.Vertex1 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                        {
                            continue;
                        }

                        if ((triangle.Vertexes.Vertex0 - triangle.Vertexes.Vertex2).LengthSquared() < MyPhysicsConfig.TriangleEpsilon)
                        {
                            continue;
                        }        */

                        MyPlane plane = new MyPlane(ref triangle.Vertexes);

                        Vector3? pt = MyUtils.GetSphereTriangleIntersection(ref newSphereInObjectSpace, ref plane, ref triangle.Vertexes);
                        if (pt == null)
                            continue;

                        pt = Vector3.Transform(pt.Value, matrix1);

                        Vector3 collisionN = -plane.Normal;
                        collisionN = Vector3.TransformNormal(collisionN, matrix1);

                        // skip triangle in case the normal is in wrong dir (narrow walls)  
                        Vector3 tempV = (interpolatedPosition - pt.Value);
                        if (Vector3.Dot(collisionN, tempV) >= 0.8f * tempV.Length())  // equivalent to if (Vector3.Dot(collisionN, Vector3.Normalize(tempV)) > 0.8f)
                        {
                            continue;
                        }

                        float depth = Vector3.Distance(pt.Value, interpolatedPosition) - sphereRadius;

                        if (numCollPts < MyPhysicsConfig.MaxContactPoints)
                        {
                            // since impulse get applied at the old position
                            Vector3 p2 = pt.Value; // body0Pos - sphereRadius * 1.1f * collisionN;                                    

                            collPtArray[numCollPts++] = new MySmallCollPointInfo(p2 - interpolatedPosition, p2 - body1Pos, GetRigidBody1().LinearVelocity, GetRigidBody2().LinearVelocity, collisionN, depth, p2);

                            /*
                            MyDebugDraw.AddDrawTriangle(
                                Vector3.Transform(triangle.Vertexes.Vertex0, matrix1),
                                Vector3.Transform(triangle.Vertexes.Vertex1, matrix1),
                                Vector3.Transform(triangle.Vertexes.Vertex2, matrix1),
                                Color.Red);
                            */
                        }

                        collNormal += collisionN;
                    }

                    if (numCollPts > 0) // break if we catch any triangles in this iteration
                        break;

                }
                if (numCollPts > 0)
                {
                    MyPhysics.physicsSystem.GetContactConstraintModule().AddContactConstraint(this, collPtArray, numCollPts);
                }
                MyPhysics.physicsSystem.GetContactConstraintModule().GetTriangleCache().PushBackTriangleList(triangles);
                MyContactInfoCache.FreeStackAlloc(collPtArray);
            }
            return false;
        }
Beispiel #28
0
        //(THE FOLLOWING FUNCTION IS CREATED FOR COMPOSED PATTERN SEARCH)
        //This function is the analogous of IsReflectionTwoRE, but in this situation the candidate
        //reflectional plane is given as input.
        public static bool IsReflectionTwoREGivenCandidateReflPlane(MyRepeatedEntity firstMyRepeatedEntity,
                                                                    MyRepeatedEntity secondMyRepeatedEntity, MyPlane candidateReflMyPlane)
        {
            //Vertex analysis for Reflection:
            var firstListOfVertices  = firstMyRepeatedEntity.listOfVertices;
            var firstNumOfVerteces   = firstListOfVertices.Count;
            var secondListOfVertices = secondMyRepeatedEntity.listOfVertices;
            var secondNumOfVerteces  = secondListOfVertices.Count;

            if (firstNumOfVerteces == secondNumOfVerteces)
            {
                int i = 0;
                while (i < firstNumOfVerteces)
                {
                    if (secondListOfVertices.FindIndex(
                            vert => vert.IsReflectionOf(firstListOfVertices[i], candidateReflMyPlane)) != -1)
                    {
                        var found =
                            secondListOfVertices.Find(
                                vert => vert.IsReflectionOf(firstListOfVertices[i], candidateReflMyPlane));

                        var scarto =
                            new MyVertex(Math.Abs(firstListOfVertices[i].Reflect(candidateReflMyPlane).x - found.x),
                                         Math.Abs(firstListOfVertices[i].Reflect(candidateReflMyPlane).y - found.y),
                                         Math.Abs(firstListOfVertices[i].Reflect(candidateReflMyPlane).z - found.z));

                        i++;
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }

            //Check of correct position of normals of all Planar face:
            if (!CheckOfPlanesForReflection(firstMyRepeatedEntity, secondMyRepeatedEntity, candidateReflMyPlane))
            {
                return(false);
            }

            ////Check of correct position of cylinder faces:
            if (!CheckOfCylindersForReflection(firstMyRepeatedEntity, secondMyRepeatedEntity, candidateReflMyPlane))
            {
                return(false);
            }

            ////CONTINUARE CON GLI ALTRI TIPI DI SUPERFICI............
            //KLdebug.Print("   ====>>> TRASLAZIONE TRA QUESTE DUE re VERIFICATA!", nameFile);
            return(true);
        }
Beispiel #29
0
        //  Add decal and all surounding triangles for voxel intersection
        static void AddDecalVoxel(MyDecalTexturesEnum decalTexture, float decalSize, float decalScale, Vector4 color, bool alphaBlendByAngle,
                                  ref MyIntersectionResultLineTriangleEx intersection, ref MyPlane rightPlane, ref MyPlane upPlane, float lightSize, float emissivity, float decalNormalOffset)
        {
            MyVoxelMap voxelMap = (MyVoxelMap)intersection.Entity;

            MyMwcVector3Int renderCellCoord     = voxelMap.GetVoxelRenderCellCoordinateFromMeters(ref intersection.IntersectionPointInWorldSpace);
            BoundingSphere  decalBoundingSphere = new BoundingSphere(intersection.IntersectionPointInWorldSpace, decalSize);

            //  If whole decal can't fit inside of render cell, we won't add any of its triangles. This is because
            //  when hiding/removing triangles after explosion, it is easier to check only one render cell.
            BoundingBox renderCellBoundingBox;

            voxelMap.GetRenderCellBoundingBox(ref renderCellCoord, out renderCellBoundingBox);

            // TODO simon - commented as an experiment. If there are bugs with decals on voxels, remove the comment below
            //if (renderCellBoundingBox.Contains(decalBoundingSphere) != ContainmentType.Contains) return;

            //  If we get null, buffer is full so no new decals can't be placed
            MyDecalsForVoxelsTriangleBuffer decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(voxelMap, ref renderCellCoord, decalTexture, ref renderCellBoundingBox);

            if (decalsBuffer == null)
            {
                return;
            }

            //  We need to create decals on neighborhood triangles too, so we check all triangles if they fall in decal's sphere and if yes, we place decal on them.
            //  We check triangles from same voxelmap or model only.

            m_neighbourTriangles.Clear();
            //intersection.VoxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, intersection.TriangleHelperIndex, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles);
            voxelMap.GetTrianglesIntersectingSphere(ref decalBoundingSphere, m_neighbourTriangles, decalsBuffer.MaxNeighbourTriangles, false);

            int trianglesToAdd = m_neighbourTriangles.Count;// +1;

            if (trianglesToAdd == 0)
            {
                return;
            }

            if (decalsBuffer.CanAddTriangles(trianglesToAdd) == true)
            {
                var normalSum = CalculateDominantNormal(m_neighbourTriangles);
                normalSum *= decalNormalOffset;

                //  Create decal for every neighbour triangleVertexes
                for (int i = 0; i < m_neighbourTriangles.Count; i++)
                {
                    trianglesToAdd--;

                    var triangle = m_neighbourTriangles[i];
                    triangle.Vertexes.Vertex0 += normalSum;
                    triangle.Vertexes.Vertex1 += normalSum;
                    triangle.Vertexes.Vertex2 += normalSum;
                    m_neighbourTriangles[i]    = triangle;

                    decalsBuffer.Add(m_neighbourTriangles[i], intersection.NormalInWorldSpace, ref rightPlane,
                                     ref upPlane, decalScale, trianglesToAdd, color, alphaBlendByAngle, lightSize, intersection.IntersectionPointInWorldSpace, emissivity);
                }
            }
        }
Beispiel #30
0
        //  Return list of triangles intersecting specified sphere. 
        //  Triangles are returned in 'retTriangles', and this list must be preallocated!
        //  Count of returned triangles is in 'retTrianglesCount'
        //public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, int ignoreTriangleWithIndex, List<MyTriangle_Vertex_Normals_Sun> retTriangles, int maxNeighbourTriangles)
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, List<MyTriangle_Vertex_Normals> retTriangles,
            int maxNeighbourTriangles, bool returnAbsoluteVoxelVertexCoordinates)
        {
            //  If sphere doesn't intersect bounding box of a voxel map, we end this method
            if (IsSphereIntersectingBoundingBoxOfThisVoxelMap(ref sphere) == false) return;


            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBox sphereBoundingBox = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSphere(sphere, ref sphereBoundingBox);
            MyMwcVector3Int cellCoordMin = GetDataCellCoordinateFromMeters(ref sphereBoundingBox.Min);
            MyMwcVector3Int cellCoordMax = GetDataCellCoordinateFromMeters(ref sphereBoundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            FixDataCellCoord(ref cellCoordMin);
            FixDataCellCoord(ref cellCoordMax);

            MyMwcVector3Int cellCoord;
            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        //  If no overlap between bounding pitch of data cell and the sphere
                        BoundingBox dataCellBoundingBox;
                        GetDataCellBoundingBox(ref cellCoord, out dataCellBoundingBox);
                        if (MyUtils.IsBoxIntersectingSphere(ref dataCellBoundingBox, ref sphere) == false) continue;

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        MyVoxelCacheCellData cachedDataCell = null;
                        using (MyVoxelCacheData.Locker.AcquireSharedUsing())
                        {
                            cachedDataCell = MyVoxelCacheData.GetCell(this, ref cellCoord, true);

                            if (cachedDataCell == null) continue;

                            for (int i = 0; i < cachedDataCell.VoxelTrianglesCount; i++)
                            {
                                //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                                if (retTriangles.Count == maxNeighbourTriangles)
                                {
                                    return;
                                }

                                MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                                MyVoxelVertex voxelVertex0 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex0];
                                MyVoxelVertex voxelVertex1 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex1];
                                MyVoxelVertex voxelVertex2 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex2];

                                MyTriangle_Vertexes triangle;
                                triangle.Vertex0 = voxelVertex0.Position + PositionLeftBottomCorner;
                                triangle.Vertex1 = voxelVertex1.Position + PositionLeftBottomCorner;
                                triangle.Vertex2 = voxelVertex2.Position + PositionLeftBottomCorner;

                                BoundingBox voxelTriangleBoundingBox = BoundingBoxHelper.InitialBox;
                                BoundingBoxHelper.AddTriangle(ref voxelTriangleBoundingBox, ref triangle.Vertex0, ref triangle.Vertex1, ref triangle.Vertex2);

                                //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                                if (MyUtils.IsBoxIntersectingSphere(ref voxelTriangleBoundingBox, ref sphere) == true)
                                {
                                    //if (ignoreTriangleWithIndex != cachedDataCell.VoxelTriangles[value].TriangleId)
                                    {
                                        MyPlane trianglePlane = new MyPlane(ref triangle);

                                        if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                                        {
                                            MyTriangle_Vertex_Normals retTriangle;
                                            retTriangle.Normals.Normal0 = voxelVertex0.Normal;
                                            retTriangle.Normals.Normal1 = voxelVertex1.Normal;
                                            retTriangle.Normals.Normal2 = voxelVertex2.Normal;

                                            // Hack: fix thix
                                            retTriangle.Binormals.Normal0 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Normals.Normal0, new Vector3(0.2341f, 0.2341f, 0.9865f)));
                                            retTriangle.Binormals.Normal1 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Normals.Normal1, new Vector3(0.2341f, 0.2341f, 0.9865f)));
                                            retTriangle.Binormals.Normal2 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Normals.Normal2, new Vector3(0.2341f, 0.2341f, 0.9865f)));

                                            retTriangle.Tangents.Normal0 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Binormals.Normal0, retTriangle.Normals.Normal0));
                                            retTriangle.Tangents.Normal1 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Binormals.Normal1, retTriangle.Normals.Normal1));
                                            retTriangle.Tangents.Normal2 = MyMwcUtils.Normalize(Vector3.Cross(retTriangle.Binormals.Normal2, retTriangle.Normals.Normal2));

                                            if (returnAbsoluteVoxelVertexCoordinates)
                                            {
                                                retTriangle.Vertexes = triangle;
                                            }
                                            else
                                            {
                                                retTriangle.Vertexes.Vertex0 = voxelVertex0.Position;
                                                retTriangle.Vertexes.Vertex1 = voxelVertex1.Position;
                                                retTriangle.Vertexes.Vertex2 = voxelVertex2.Position;
                                            }

                                            retTriangles.Add(retTriangle);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        return;
                    }

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals  triangleNormals;
                            MyTriangle_Normals  triangleBinormals;
                            MyTriangle_Normals  triangleTangents;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

                            /*
                             * triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                             * triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                             * triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                             */

                            triangleNormals.Normal0 = m_model.GetVertexNormal(triangleIndices.I0);
                            triangleNormals.Normal1 = m_model.GetVertexNormal(triangleIndices.I2);
                            triangleNormals.Normal2 = m_model.GetVertexNormal(triangleIndices.I1);

                            if (MinerWars.AppCode.Game.Render.MyRenderConstants.RenderQualityProfile.ForwardRender)
                            {
                                triangleBinormals.Normal0 = triangleNormals.Normal0;
                                triangleBinormals.Normal1 = triangleNormals.Normal1;
                                triangleBinormals.Normal2 = triangleNormals.Normal2;

                                triangleTangents.Normal0 = triangleNormals.Normal0;
                                triangleTangents.Normal1 = triangleNormals.Normal1;
                                triangleTangents.Normal2 = triangleNormals.Normal2;
                            }
                            else
                            {
                                triangleBinormals.Normal0 = m_model.GetVertexBinormal(triangleIndices.I0);
                                triangleBinormals.Normal1 = m_model.GetVertexBinormal(triangleIndices.I2);
                                triangleBinormals.Normal2 = m_model.GetVertexBinormal(triangleIndices.I1);

                                triangleTangents.Normal0 = m_model.GetVertexTangent(triangleIndices.I0);
                                triangleTangents.Normal1 = m_model.GetVertexTangent(triangleIndices.I2);
                                triangleTangents.Normal2 = m_model.GetVertexTangent(triangleIndices.I1);
                            }

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normals retTriangle;
                                    retTriangle.Vertexes  = triangle;
                                    retTriangle.Normals   = triangleNormals;
                                    retTriangle.Binormals = triangleBinormals;
                                    retTriangle.Tangents  = triangleTangents;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #32
0
        //  Return true if voxel map intersects specified sphere.
        //  This method doesn't return exact point of intersection or any additional data.
        //  We don't look for closest intersection - so we stop on first intersection found.
        public override bool GetIntersectionWithSphere(ref BoundingSphere sphere)
        {

            //Lock.AcquireReaderLock(Timeout.Infinite);
            //  If sphere doesn't intersect bounding box of a voxel map, we end this method
            if (IsSphereIntersectingBoundingBoxOfThisVoxelMap(ref sphere) == false) return false;

            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBox sphereBoundingBox = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSphere(sphere, ref sphereBoundingBox);
            MyMwcVector3Int cellCoordMin = GetDataCellCoordinateFromMeters(ref sphereBoundingBox.Min);
            MyMwcVector3Int cellCoordMax = GetDataCellCoordinateFromMeters(ref sphereBoundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            FixDataCellCoord(ref cellCoordMin);
            FixDataCellCoord(ref cellCoordMax);

            MyMwcVector3Int cellCoord;
            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox dataCellBoundingBox;
                        GetDataCellBoundingBox(ref cellCoord, out dataCellBoundingBox);
                        if (MyUtils.IsBoxIntersectingSphere(ref dataCellBoundingBox, ref sphere) == false) continue;

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        MyVoxelCacheCellData cachedDataCell = null;
                        using (MyVoxelCacheData.Locker.AcquireSharedUsing())
                        {
                            cachedDataCell = MyVoxelCacheData.GetCell(this, ref cellCoord, true);

                            if (cachedDataCell == null) continue;

                            for (int i = 0; i < cachedDataCell.VoxelTrianglesCount; i++)
                            {
                                MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                                MyVoxelVertex voxelVertex0 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex0];
                                MyVoxelVertex voxelVertex1 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex1];
                                MyVoxelVertex voxelVertex2 = cachedDataCell.VoxelVertices[voxelTriangle.VertexIndex2];

                                MyTriangle_Vertexes triangle;
                                triangle.Vertex0 = voxelVertex0.Position + PositionLeftBottomCorner;
                                triangle.Vertex1 = voxelVertex1.Position + PositionLeftBottomCorner;
                                triangle.Vertex2 = voxelVertex2.Position + PositionLeftBottomCorner;

                                BoundingBox voxelTriangleBoundingBox = BoundingBoxHelper.InitialBox;
                                BoundingBoxHelper.AddTriangle(ref voxelTriangleBoundingBox, ref triangle.Vertex0, ref triangle.Vertex1, ref triangle.Vertex2);

                                //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                                if (MyUtils.IsBoxIntersectingSphere(ref voxelTriangleBoundingBox, ref sphere) == true)
                                {
                                    //if (ignoreTriangleWithIndex != cachedDataCell.VoxelTriangles[value].TriangleId)
                                    {
                                        MyPlane trianglePlane = new MyPlane(ref triangle);

                                        if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                                        {
                                            //  If intersection found - we are finished. We don't need to look for more.
                                            return true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return false;
        }
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphere sphere, Vector3? referenceNormalVector, float? maxAngle, List<MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            //  Check if sphere intersects bounding box of this node
            //if (m_boundingBox.Contains(sphere) == ContainmentType.Disjoint) return;
            if (MyUtils.IsBoxIntersectingSphere(ref m_boundingBox, ref sphere) == false) return;

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                if (retTriangles.Count == maxNeighbourTriangles) return;

                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                {
                    //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes triangle;
                        MyTriangle_Normals triangleNormals;
                        MyTriangle_Normals triangleBinormals;
                        MyTriangle_Normals triangleTangents;

                        MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                        triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2 = model.GetVertex(triangleIndices.I1);
                        triangleNormals.Normal0 = model.GetVertexNormal(triangleIndices.I0);
                        triangleNormals.Normal1 = model.GetVertexNormal(triangleIndices.I2);
                        triangleNormals.Normal2 = model.GetVertexNormal(triangleIndices.I1);

                        triangleBinormals.Normal0 = model.GetVertexBinormal(triangleIndices.I0);
                        triangleBinormals.Normal1 = model.GetVertexBinormal(triangleIndices.I2);
                        triangleBinormals.Normal2 = model.GetVertexBinormal(triangleIndices.I1);

                        triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0);
                        triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2);
                        triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1);

                        MyPlane trianglePlane = new MyPlane(ref triangle);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                        {
                            Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                            {
                                MyTriangle_Vertex_Normals retTriangle;
                                retTriangle.Vertexes = triangle;
                                retTriangle.Normals = triangleNormals;
                                retTriangle.Binormals = triangleBinormals;
                                retTriangle.Tangents = triangleTangents;

                                retTriangles.Add(retTriangle);
                            }
                        }
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    //m_childs[value].GetTrianglesIntersectingSphere(physObject, ref sphere, referenceNormalVector, maxAngle, ignoreTriangleWithIndex, retTriangles, maxNeighbourTriangles);
                    m_childs[i].GetTrianglesIntersectingSphere(model, ref sphere, referenceNormalVector, maxAngle, retTriangles, maxNeighbourTriangles);
                }
            }
        }
        internal bool Intersects(ref BoundingSphere sphere)
        {
            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBox sphereBoundingBox = BoundingBox.CreateInvalid();
            sphereBoundingBox.Include(ref sphere);
            Vector3I cellCoordMin = GetCellCoordinateFromMeters(ref sphereBoundingBox.Min);
            Vector3I cellCoordMax = GetCellCoordinateFromMeters(ref sphereBoundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            FixDataCellCoord(ref cellCoordMin);
            FixDataCellCoord(ref cellCoordMax);

            Vector3I cellCoord;
            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref sphere) == false)
                            continue;

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        CellData cachedDataCell = GetCell(MyLodTypeEnum.LOD0, ref cellCoord);

                        if (cachedDataCell == null) continue;

                        for (int i = 0; i < cachedDataCell.VoxelTrianglesCount; i++)
                        {
                            MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                            MyTriangle_Vertexes triangle;
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);
                            triangle.Vertex0 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex1 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex2 += m_voxelMap.PositionLeftBottomCorner;

                            BoundingBox voxelTriangleBoundingBox = BoundingBox.CreateInvalid();
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex0);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex1);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex2);

                            //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                            if (voxelTriangleBoundingBox.Intersects(ref sphere))
                            {
                                MyPlane trianglePlane = new MyPlane(ref triangle);

                                if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                                {
                                    //  If intersection found - we are finished. We don't need to look for more.
                                    Profiler.End();
                                    return true;
                                }
                            }
                        }

                    }
                }
            }

            return false;
        }
        public void Add(MyTriangle_Vertex_Normals triangle, Vector3 normal, ref MyPlane rightPlane, ref MyPlane upPlane, float decalScale, float decalSize, int remainingTrianglesOfThisDecal, Vector4 color, bool alphaBlendByAngle, float lightSize, Vector3 position, float emissivity)
        {
            //  We can't add triangles while fading out
            //if (m_status == MyDecalsBufferState.FADING_OUT) return;            

            MyDecalTriangle decalTriangle = m_freeTriangles.Pop();
            decalTriangle.Start(lightSize);
            decalTriangle.Emissivity = emissivity;
            //decalTriangle.RandomOffset = MyMwcUtils.GetRandomFloat(0.0f, MathHelper.Pi);
            decalTriangle.RandomOffset = MyMinerGame.TotalGamePlayTimeInMilliseconds;
            decalTriangle.Position = position;

            // We must repack vertex positions before copying to new triange, to avoid Z-fight.
            decalTriangle.Position0 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex0);
            decalTriangle.Position1 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex1);
            decalTriangle.Position2 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex2);

            //  Texture coords
            decalTriangle.TexCoord0 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref upPlane));
            decalTriangle.TexCoord1 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref upPlane));
            decalTriangle.TexCoord2 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref upPlane));

            //  Alpha
            decalTriangle.Color0 = color;
            decalTriangle.Color1 = color;
            decalTriangle.Color2 = color;
            if (alphaBlendByAngle)
            {
                decalTriangle.Color0.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal0);
                decalTriangle.Color1.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal1);
                decalTriangle.Color2.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal2);
            }

            AdjustAlphaByDistance(normal, decalSize, position, decalTriangle);

            //  Bump mapping
            decalTriangle.Normal0 = triangle.Normals.Normal0;
            decalTriangle.Normal1 = triangle.Normals.Normal1;
            decalTriangle.Normal2 = triangle.Normals.Normal2;

            decalTriangle.Binormal0 = triangle.Binormals.Normal0;
            decalTriangle.Binormal1 = triangle.Binormals.Normal1;
            decalTriangle.Binormal2 = triangle.Binormals.Normal2;

            decalTriangle.Tangent0 = triangle.Tangents.Normal0;
            decalTriangle.Tangent1 = triangle.Tangents.Normal1;
            decalTriangle.Tangent2 = triangle.Tangents.Normal2;

            decalTriangle.RemainingTrianglesOfThisDecal = remainingTrianglesOfThisDecal;

            m_trianglesQueue.Enqueue(decalTriangle);
        }
Beispiel #36
0
        public void Add(MyTriangle_Vertex_Normals triangle, Vector3 normal, ref MyPlane rightPlane, ref MyPlane upPlane, float decalScale, float decalSize, int remainingTrianglesOfThisDecal, Vector4 color, bool alphaBlendByAngle, float lightSize, Vector3 position, float emissivity)
        {
            //  We can't add triangles while fading out
            //if (m_status == MyDecalsBufferState.FADING_OUT) return;

            MyDecalTriangle decalTriangle = m_freeTriangles.Pop();

            decalTriangle.Start(lightSize);
            decalTriangle.Emissivity = emissivity;
            //decalTriangle.RandomOffset = MyMwcUtils.GetRandomFloat(0.0f, MathHelper.Pi);
            decalTriangle.RandomOffset = MyMinerGame.TotalGamePlayTimeInMilliseconds;
            decalTriangle.Position     = position;

            // We must repack vertex positions before copying to new triange, to avoid Z-fight.
            decalTriangle.Position0 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex0);
            decalTriangle.Position1 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex1);
            decalTriangle.Position2 = VF_Packer.RepackModelPosition(ref triangle.Vertexes.Vertex2);

            //  Texture coords
            decalTriangle.TexCoord0 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position0, ref upPlane));
            decalTriangle.TexCoord1 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position1, ref upPlane));
            decalTriangle.TexCoord2 = new Vector2(
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref rightPlane),
                0.5f + decalScale * MyUtils.GetDistanceFromPointToPlane(ref decalTriangle.Position2, ref upPlane));

            //  Alpha
            decalTriangle.Color0 = color;
            decalTriangle.Color1 = color;
            decalTriangle.Color2 = color;
            if (alphaBlendByAngle)
            {
                decalTriangle.Color0.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal0);
                decalTriangle.Color1.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal1);
                decalTriangle.Color2.W = GetAlphaByAngleDiff(ref normal, ref triangle.Normals.Normal2);
            }

            AdjustAlphaByDistance(normal, decalSize, position, decalTriangle);

            //  Bump mapping
            decalTriangle.Normal0 = triangle.Normals.Normal0;
            decalTriangle.Normal1 = triangle.Normals.Normal1;
            decalTriangle.Normal2 = triangle.Normals.Normal2;

            decalTriangle.Binormal0 = triangle.Binormals.Normal0;
            decalTriangle.Binormal1 = triangle.Binormals.Normal1;
            decalTriangle.Binormal2 = triangle.Binormals.Normal2;

            decalTriangle.Tangent0 = triangle.Tangents.Normal0;
            decalTriangle.Tangent1 = triangle.Tangents.Normal1;
            decalTriangle.Tangent2 = triangle.Tangents.Normal2;

            decalTriangle.RemainingTrianglesOfThisDecal = remainingTrianglesOfThisDecal;

            m_trianglesQueue.Enqueue(decalTriangle);
        }