Пример #1
0
            public MovementPlanner.MovementNode GenerateNode(Vector3D position, double facingAngle, double desiredSpeed, Vector3D goal)
            {
                var groundPlane = new PlaneD(CurrentLocation, UpDirection);

                var referencePoint    = new Vector3D(position);
                var projectedPoint    = groundPlane.ProjectPoint(ref referencePoint);
                var projectedX        = (projectedPoint - CurrentLocation).Dot(X_Axis);
                var projectedY        = (projectedPoint - CurrentLocation).Dot(Y_Axis);
                var projectedPosition = new Vector2D(projectedX, projectedY);

                referencePoint = new Vector3D(goal);
                projectedPoint = groundPlane.ProjectPoint(ref referencePoint);
                projectedX     = (projectedPoint - CurrentLocation).Dot(X_Axis);
                projectedY     = (projectedPoint - CurrentLocation).Dot(Y_Axis);
                var projectedGoal = new Vector2D(projectedX, projectedY);

                return(GenerateNode(projectedPosition, facingAngle, desiredSpeed, projectedGoal));
            }
Пример #2
0
            /// <summary>
            /// Generates a movement planner from a terrain map with a valid up direction.
            /// </summary>
            /// <remarks>Does not copy points. Must be done before adding any points.</remarks>
            public void GenerateMovementPlanner()
            {
                var groundPlane = new PlaneD(CurrentLocation, UpDirection);

                var referenceCenter  = new Vector3D(terrainMap_.Center);
                var projectedCenter  = groundPlane.ProjectPoint(ref referenceCenter);
                var projectedCenterX = (projectedCenter - CurrentLocation).Dot(X_Axis);
                var projectedCenterY = (projectedCenter - CurrentLocation).Dot(Y_Axis);
                var flatCenter       = new Vector2D(projectedCenterX, projectedCenterY);

                var referenceExtents = new Vector3D(terrainMap_.Extents);
                var projectedExtents = groundPlane.ProjectPoint(ref referenceExtents);
                var maxExtent        = Math.Abs((projectedExtents - CurrentLocation).Dot(X_Axis));

                maxExtent = Math.Max(maxExtent, Math.Abs((projectedExtents - CurrentLocation).Dot(Y_Axis)));
                var flatExtents = new Vector2D(maxExtent, maxExtent);

                movementPlanner_ = new MovementPlanner(flatCenter, flatExtents);
            }
        private static Vector3D CollideWithTriangles(BoundingSphereD sphere, Vector3D velocity,
                                                     Triangle[] triangles, int recurssionDepth)
        {
            if (recurssionDepth > MAX_RECURSSION_DEPTH)
            {
                return(Vector3D.Zero);
            }

            CollisionResult collision = CollidesWith(sphere, triangles, velocity);

            if (!collision.FoundCollision)
            {
                return(velocity);
            }

            Vector3D originalDestinationPoint = sphere.Center + velocity;

            double intersectionDistance = velocity.Length() * collision.IntersectionTime;
            //Only update if we aren't very close, and if so only move very close
            //if (intersectionDistance >= VeryCloseDistance)
            //{
            Vector3D normalizedVelocity = velocity.Normalized();

            velocity       = (intersectionDistance - VeryCloseDistance) * normalizedVelocity;
            sphere.Center += velocity;

            //Fake the collision results to match the very close approximation
            collision.IntersectionPoint -= normalizedVelocity * VeryCloseDistance;
            //}

            PlaneD   slidingPlane     = CollisionExtensions.Plane(collision.IntersectionPoint, sphere.Center - collision.IntersectionPoint);
            Vector3D destinationPoint = originalDestinationPoint.ProjectOn(slidingPlane);

            Vector3D newVelocityVector = destinationPoint - collision.IntersectionPoint;

            if (newVelocityVector.Length() < VeryCloseDistance)
            {
                return(velocity);
            }

            return(velocity + CollideWithTriangles(sphere, newVelocityVector, triangles, recurssionDepth + 1));
        }
Пример #4
0
            public static Vector3D GetXYZDistance(IMyTerminalBlock block, Vector3D targetPos)
            {
                Vector3D myPos          = block.GetPosition();
                Vector3D targetVector   = Vector3D.Subtract(targetPos, myPos);
                double   targetDistance = targetVector.Length();

                targetVector.Normalize();

                PlaneD forwardReversePlane = new PlaneD(block.WorldMatrix.Forward, 0);
                PlaneD leftRightPlane      = new PlaneD(block.WorldMatrix.Left, 0);
                PlaneD upDownPlane         = new PlaneD(block.WorldMatrix.Up, 0);

                float forwardReverseDistance = Convert.ToSingle(Math.Sin(forwardReversePlane.DotNormal(targetVector)) * targetDistance);
                float leftRightDistance      = Convert.ToSingle(Math.Sin(leftRightPlane.DotNormal(targetVector)) * targetDistance);
                float upDownDistance         = Convert.ToSingle(Math.Sin(upDownPlane.DotNormal(targetVector)) * targetDistance);

                Vector3D xyzDistance = new Vector3D();

                xyzDistance.X = leftRightDistance;
                xyzDistance.Y = forwardReverseDistance;
                xyzDistance.Z = upDownDistance;

                return(xyzDistance);
            }
Пример #5
0
        public bool Intersects(ref BoundingSphereD localSphere)
        {
            MyPrecalcComponent.AssertUpdateThread();

            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBoxD sphereBoundingBox = BoundingBoxD.CreateInvalid();

            sphereBoundingBox.Include(ref localSphere);
            Vector3I cellCoordMin, cellCoordMax;

            {
                Vector3D minD = sphereBoundingBox.Min;
                Vector3D maxD = sphereBoundingBox.Max;
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref minD, out cellCoordMin);
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref maxD, out cellCoordMax);
            }

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

            MyCellCoord cell = new MyCellCoord();

            for (cell.CoordInLod.X = cellCoordMin.X; cell.CoordInLod.X <= cellCoordMax.X; cell.CoordInLod.X++)
            {
                for (cell.CoordInLod.Y = cellCoordMin.Y; cell.CoordInLod.Y <= cellCoordMax.Y; cell.CoordInLod.Y++)
                {
                    for (cell.CoordInLod.Z = cellCoordMin.Z; cell.CoordInLod.Z <= cellCoordMax.Z; cell.CoordInLod.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref localSphere) == 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 cachedData = GetCell(ref cell);

                        if (cachedData == null)
                        {
                            continue;
                        }

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

                            MyTriangle_Vertexes triangle;
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);

                            BoundingBox localTriangleAABB = BoundingBox.CreateInvalid();
                            localTriangleAABB.Include(ref triangle.Vertex0);
                            localTriangleAABB.Include(ref triangle.Vertex1);
                            localTriangleAABB.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 (localTriangleAABB.Intersects(ref localSphere))
                            {
                                PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

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

            return(false);
        }
        public bool GetIntersectionWithSphere(IMyEntity entity, ref BoundingSphereD sphere)
        {
            //  Transform sphere from world space to object space
            MatrixD worldInv = entity.PositionComp.WorldMatrixNormalizedInv;
            Vector3 positionInObjectSpace = (Vector3)Vector3D.Transform(sphere.Center, ref worldInv);
            BoundingSphereD sphereInObjectSpace = new BoundingSphereD(positionInObjectSpace, (float)sphere.Radius);

            var aabb = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphereInObjectSpace;
            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());
            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 (triangleBoundingBox.Intersects(ref sphereInObjectSpace))
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertices 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);

                        PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                        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;
        }
Пример #7
0
        public void CollectData()
        {
            //Rectangle3D rect = new Rectangle3D(new Vector3D(-5, 0, -5), new Vector3D(5, 0, 5), new PlaneD(new Vector3D(0, 1, 0), 0));
            //Vector3D iPoint;
            //bool result = rect.IntersectWithLine(new Vector3D(5, 5, 0), new Vector3D(0, -1, 0), out iPoint);

            // create frame buffer to store data
            buffer = new FrameData(viewArea.Width, viewArea.Height, false, Color.Black);

            CameraView cView = new CameraView();

            cView.Centre    = new Vector3D(3, 5, 3);
            cView.Direction = cView.Centre - new Vector3D(0, 0, 0);
            cView.Direction.Normalize();
            cView.XUV = Vector3D.Cross(cView.Direction, Vector3D.Up);
            cView.XUV.Normalize();
            cView.YUV = Vector3D.Cross(cView.XUV, cView.Direction);
            cView.YUV.Normalize();
            cView.ViewArea = new Vector2D(1, 1);
            Vector3D halfX = cView.XUV * 0.5 * cView.ViewArea.X;
            Vector3D halfY = cView.YUV * 0.5 * cView.ViewArea.Y;

            cView.Corners = new Vector3D[] { cView.Centre - halfX + halfY, // top left
                                             cView.Centre + halfX + halfY, // top right
                                             cView.Centre - halfX - halfY, // bottom left
                                             cView.Centre + halfX - halfY  // bottom right
            };
            cView.Frustum = new PlaneD[] { PlaneD.FromPointNormal(cView.Corners[0], -cView.XUV),
                                           PlaneD.FromPointNormal(cView.Corners[1], cView.XUV),
                                           PlaneD.FromPointNormal(cView.Corners[2], cView.YUV),
                                           PlaneD.FromPointNormal(cView.Corners[3], -cView.YUV) };
            cView.Area            = viewArea;
            cView.ProjectionScale = new Vector2D(0.2, 0.2);

            texture = Bitmap.FromFile("c:/checkers2.bmp");
            //Bitmap texture2 = (Bitmap)Bitmap.FromFile("c:/newheightmap.jpg");

            // setup temp scene
            SimpleSceneManager scene = new SimpleSceneManager(new RGBA_D(0.2, 0.2, 0.2, 1));

            /*scene.AddObject(new TriangleGroupSceneObject(new Vector3D(0, 0, 2),
             *                                           new MaterialShader(new RGBA_D(1, 1, 1, 1),
             *                                                              15, 0.1, 0, 0, 1),
             *                                           1.1));*/
            /*scene.AddObject(new SphereSceneObject(new Vector3D(0, 0, 0),
             *                                    new MaterialShader(new RGBA_D(0, 0, 1, 1),
             *                                                       15, 0, 0, 0, 1),
             *                                    1));*/
            /*scene.AddObject(new SphereSceneObject(new Vector3D(0, 0, 0),
             *                                    new MaterialShader(new RGBA_D(1, 0, 0, 1),
             *                                                       15, 1, 0, 0, 1),
             *                                    1));
             * scene.AddObject(new SphereSceneObject(new Vector3D(-3, -1, -3),
             *                                    new MaterialShader(new RGBA_D(0.2, 1, 0.1, 1),
             *                                                       15, 0, 0, 0, 1, texture2),
             *                                    1));
             * scene.AddObject(new SphereSceneObject(new Vector3D(2, 0, 0),
             *                                    new MaterialShader(new RGBA_D(1, 1, 0, 1),
             *                                                       10, 0.1, 0, 0, 1),
             *                                    1));
             * scene.AddObject(new SphereSceneObject(new Vector3D(0.5, 1, 0),
             *                                    new MaterialShader(new RGBA_D(1, 1, 1, 1),
             *                                                       5, 0, 0, 0, 1, texture),
             *                                    0.8));
             *
             * scene.AddObject(new PlaneSceneObject(new Vector3D(0, -5, 0), new Vector3D(0, 1, 0),
             *                                   new MaterialShader(new RGBA_D(0.1, 0.1, 0.1, 1.0),
             *                                                      5, 0, 0, 0, 1), -1));
             */
            scene.AddObject(new HeightFieldObject(new Vector3D(),
                                                  new MaterialShader(new RGBA_D(1, 1, 1, 1),
                                                                     5, 0, 0, 0, 1, texture),
                                                  new Vector2D(2, 2), (Bitmap)texture));

            /*
             * IOpticalSceneObject obj;
             * Vector3D iPos;
             * double iDist;
             * uint subIdx;
             * scene.GetFirstIntersection(new Vector3D(10, 0.5, 0), new Vector3D(1, 0, 0), 100, out obj, out iPos, out iDist, out subIdx);
             */
            // collect data
            DateTime start        = DateTime.Now;
            RayGroup initialGroup = new RayGroup(true, 100,
                                                 cView.Area, scene, null, buffer, cView);

            rayDispatch.DispatchRayGroupReq(initialGroup);

            rayDispatch.WaitForCompletion();
            DateTime end  = DateTime.Now;
            TimeSpan time = end - start;

            string aaFilter = buffer.AALayer != null ? "true[5_point_star]" : "false";

            stats = string.Format("threads={0} rays={1} pixels={2} time={3}ms AA={4}", rayDispatch.ProcessedThreads,
                                  rayDispatch.ProcessedRays,
                                  viewArea.Width * viewArea.Height,
                                  time.TotalMilliseconds,
                                  aaFilter);
        }
Пример #8
0
        public override void Draw()
        {
            ProfilerShort.Begin("base.Draw()");
            base.Draw();

            ProfilerShort.BeginNextBlock("DebugDraw");
            DebugDraw();

            if (BlockCreationIsActivated)
            {
                MyHud.Crosshair.Recenter();
            }

            if (!IsActivated || CurrentBlockDefinition == null)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            this.DrawGuiIndicators();

            if (!BuildInputValid)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            ProfilerShort.BeginNextBlock("DrawBuildingStepsCount");
            DrawBuildingStepsCount(m_gizmo.SpaceDefault.m_startBuild, m_gizmo.SpaceDefault.m_startRemove, m_gizmo.SpaceDefault.m_continueBuild, ref m_gizmo.SpaceDefault.m_localMatrixAdd);
            ProfilerShort.End();

            bool addPos = m_gizmo.SpaceDefault.m_startBuild.HasValue;
            bool removePos = false;

            float gridSize = 0;
            if (CurrentBlockDefinition != null)
                gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);

            if (DynamicMode)
            {
                PlaneD cameraPlane = new PlaneD(MySector.MainCamera.Position, MySector.MainCamera.UpVector);
                Vector3D projectedPoint = IntersectionStart;
                projectedPoint = cameraPlane.ProjectPoint(ref projectedPoint);
                Vector3D freePlacementIntersectionPoint = projectedPoint + IntersectionDistance * IntersectionDirection;
                
                if (m_hitInfo != null)
                    freePlacementIntersectionPoint = m_hitInfo.Value.Position;

                addPos = this.CaluclateDynamicModePos(freePlacementIntersectionPoint, IsDynamicOverride());
                MyCoordinateSystem.Static.Visible = false;
            }
            else
            {
                if (m_gizmo.SpaceDefault.m_startBuild == null && m_gizmo.SpaceDefault.m_startRemove == null)
                {
                    if (!FreezeGizmo)
                    {
                        if (CurrentGrid != null)
                        {
                            MyCoordinateSystem.Static.Visible = false;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for grid");
                            addPos = GetAddAndRemovePositions(gridSize, PlacingSmallGridOnLargeStatic,
                                out m_gizmo.SpaceDefault.m_addPos, out m_gizmo.SpaceDefault.m_addPosSmallOnLarge,
                                out m_gizmo.SpaceDefault.m_addDir,
                                out m_gizmo.SpaceDefault.m_removePos, out m_gizmo.SpaceDefault.m_removeBlock,
                                out m_gizmo.SpaceDefault.m_blockIdInCompound,
                                m_gizmo.SpaceDefault.m_removeBlocksInMultiBlock);

                            if (addPos)
                            {
                                if (PlacingSmallGridOnLargeStatic)
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPosSmallOnLarge.Value;
                                else
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPos;

                                m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd * CurrentGrid.WorldMatrix;

                                var normal = GetSingleMountPointNormal();
                                // Gizmo add dir can be zero in some cases
                                if (normal.HasValue && GridAndBlockValid && m_gizmo.SpaceDefault.m_addDir != Vector3I.Zero)
                                {
                                    m_gizmo.SetupLocalAddMatrix(m_gizmo.SpaceDefault, normal.Value);
                                }
                            }
                            ProfilerShort.End();
                        }
                        else
                        {
                            MyCoordinateSystem.Static.Visible = true;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for voxel");
                            Vector3D localSnappedPos = m_lastLocalCoordSysData.LocalSnappedPos;
                            if (!CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter)
                                localSnappedPos -= new Vector3D(0.5 * gridSize, 0.5 * gridSize, -0.5 * gridSize);

                            Vector3I gridCoord = Vector3I.Round(localSnappedPos / gridSize);

                            m_gizmo.SpaceDefault.m_addPos = gridCoord;
                            m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_lastLocalCoordSysData.LocalSnappedPos;
                            m_gizmo.SpaceDefault.m_worldMatrixAdd = m_lastLocalCoordSysData.Origin.TransformMatrix;

                            addPos = true;
                            ProfilerShort.End();
                        }

                    }

                    Debug.Assert(!m_gizmo.SpaceDefault.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix");

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                        removePos = true;

                }
            }

            ProfilerShort.Begin("buildingDisabledByCockpit");
            bool buildingDisabledByCockpit = MySession.Static.ControlledEntity != null && MySession.Static.ControlledEntity is MyCockpit && !SpectatorIsBuilding;
            
            if (!buildingDisabledByCockpit)
            {
                if (IsInSymmetrySettingMode)
                {
                    m_gizmo.SpaceDefault.m_continueBuild = null;
                    addPos = false;
                    removePos = false;

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        var min = (m_gizmo.SpaceDefault.m_removeBlock.Min * CurrentGrid.GridSize);
                        var max = (m_gizmo.SpaceDefault.m_removeBlock.Max * CurrentGrid.GridSize);

                        Vector3 center = (min + max) * 0.5f;

                        Color color = DrawSymmetryPlane(m_symmetrySettingMode, CurrentGrid, center);

                        DrawSemiTransparentBox(CurrentGrid, m_gizmo.SpaceDefault.m_removeBlock, color.ToVector4());
                    }
                }

                if (CurrentGrid != null && (UseSymmetry || IsInSymmetrySettingMode))
                {
                    if (CurrentGrid.XSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.XSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.XSymmetryOdd ? MySymmetrySettingModeEnum.XPlaneOdd : MySymmetrySettingModeEnum.XPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.YSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.YSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.YSymmetryOdd ? MySymmetrySettingModeEnum.YPlaneOdd : MySymmetrySettingModeEnum.YPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.ZSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.ZSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.ZSymmetryOdd ? MySymmetrySettingModeEnum.ZPlaneOdd : MySymmetrySettingModeEnum.ZPlane, CurrentGrid, center);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("UpdateGizmos");
            UpdateGizmos(addPos, removePos, true);
            
            ProfilerShort.BeginNextBlock("UpdateRenderInstanceData");
            m_renderData.UpdateRenderInstanceData();

            ProfilerShort.BeginNextBlock("CurrentVoxelBase");
            if (CurrentGrid == null || (DynamicMode && CurrentGrid != null))
            {
                MatrixD drawMatrix = m_gizmo.SpaceDefault.m_worldMatrixAdd;
                Vector3D rotatedModelOffset;
                Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref drawMatrix, out rotatedModelOffset);
                drawMatrix.Translation = drawMatrix.Translation + rotatedModelOffset;

                m_renderData.UpdateRenderEntitiesData(drawMatrix, UseTransparency, CurrentBlockScale);
            }
            else
            {
                m_renderData.UpdateRenderEntitiesData(CurrentGrid.WorldMatrix, UseTransparency);
            }

            ProfilerShort.BeginNextBlock("UpdateBlockInfoHud");
            UpdateBlockInfoHud();
            ProfilerShort.End();

        }
Пример #9
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals  triangleNormals;
                            //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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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.Vertices = triangle;
                                    retTriangle.Normals  = triangleNormals;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #10
0
        public override void Draw()
        {
            ProfilerShort.Begin("base.Draw()");
            base.Draw();

            ProfilerShort.BeginNextBlock("DebugDraw");
            DebugDraw();

            if (BlockCreationIsActivated)
            {
                MyHud.Crosshair.Recenter();
            }

            if (!IsActivated || CurrentBlockDefinition == null)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            this.DrawGuiIndicators();

            if (!BuildInputValid)
            {
                this.ClearRenderData();
                ProfilerShort.End();
                return;
            }


            ProfilerShort.BeginNextBlock("DrawBuildingStepsCount");
            DrawBuildingStepsCount(m_gizmo.SpaceDefault.m_startBuild, m_gizmo.SpaceDefault.m_startRemove, m_gizmo.SpaceDefault.m_continueBuild, ref m_gizmo.SpaceDefault.m_localMatrixAdd);
            ProfilerShort.End();

            bool addPos    = m_gizmo.SpaceDefault.m_startBuild.HasValue;
            bool removePos = false;

            float gridSize = 0;

            if (CurrentBlockDefinition != null)
            {
                gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize);
            }

            if (DynamicMode)
            {
                PlaneD   cameraPlane    = new PlaneD(MySector.MainCamera.Position, MySector.MainCamera.UpVector);
                Vector3D projectedPoint = IntersectionStart;
                projectedPoint = cameraPlane.ProjectPoint(ref projectedPoint);
                Vector3D freePlacementIntersectionPoint = projectedPoint + IntersectionDistance * IntersectionDirection;

                if (m_hitInfo != null)
                {
                    freePlacementIntersectionPoint = m_hitInfo.Value.Position;
                }

                addPos = this.CaluclateDynamicModePos(freePlacementIntersectionPoint, IsDynamicOverride());
                MyCoordinateSystem.Static.Visible = false;
            }
            else
            {
                if (m_gizmo.SpaceDefault.m_startBuild == null && m_gizmo.SpaceDefault.m_startRemove == null)
                {
                    if (!FreezeGizmo)
                    {
                        if (CurrentGrid != null)
                        {
                            MyCoordinateSystem.Static.Visible = false;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for grid");
                            addPos = GetAddAndRemovePositions(gridSize, PlacingSmallGridOnLargeStatic,
                                                              out m_gizmo.SpaceDefault.m_addPos, out m_gizmo.SpaceDefault.m_addPosSmallOnLarge,
                                                              out m_gizmo.SpaceDefault.m_addDir,
                                                              out m_gizmo.SpaceDefault.m_removePos, out m_gizmo.SpaceDefault.m_removeBlock,
                                                              out m_gizmo.SpaceDefault.m_blockIdInCompound,
                                                              m_gizmo.SpaceDefault.m_removeBlocksInMultiBlock);

                            if (addPos)
                            {
                                if (PlacingSmallGridOnLargeStatic)
                                {
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPosSmallOnLarge.Value;
                                }
                                else
                                {
                                    m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPos;
                                }

                                m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd * CurrentGrid.WorldMatrix;

                                var normal = GetSingleMountPointNormal();
                                // Gizmo add dir can be zero in some cases
                                if (normal.HasValue && GridAndBlockValid && m_gizmo.SpaceDefault.m_addDir != Vector3I.Zero)
                                {
                                    m_gizmo.SetupLocalAddMatrix(m_gizmo.SpaceDefault, normal.Value);
                                }
                            }
                            ProfilerShort.End();
                        }
                        else
                        {
                            MyCoordinateSystem.Static.Visible = true;
                            ProfilerShort.Begin("MyCubeBuilder.Draw() - Calculate for voxel");
                            Vector3D localSnappedPos = m_lastLocalCoordSysData.LocalSnappedPos;
                            if (!CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter)
                            {
                                localSnappedPos -= new Vector3D(0.5 * gridSize, 0.5 * gridSize, -0.5 * gridSize);
                            }

                            Vector3I gridCoord = Vector3I.Round(localSnappedPos / gridSize);

                            m_gizmo.SpaceDefault.m_addPos = gridCoord;
                            m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_lastLocalCoordSysData.LocalSnappedPos;
                            m_gizmo.SpaceDefault.m_worldMatrixAdd             = m_lastLocalCoordSysData.Origin.TransformMatrix;

                            addPos = true;
                            ProfilerShort.End();
                        }
                    }

                    Debug.Assert(!m_gizmo.SpaceDefault.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix");

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        removePos = true;
                    }
                }
            }

            ProfilerShort.Begin("buildingDisabledByCockpit");
            bool buildingDisabledByCockpit = MySession.Static.ControlledEntity != null && MySession.Static.ControlledEntity is MyCockpit && !SpectatorIsBuilding;

            if (!buildingDisabledByCockpit)
            {
                if (IsInSymmetrySettingMode)
                {
                    m_gizmo.SpaceDefault.m_continueBuild = null;
                    addPos    = false;
                    removePos = false;

                    if (m_gizmo.SpaceDefault.m_removeBlock != null)
                    {
                        var min = (m_gizmo.SpaceDefault.m_removeBlock.Min * CurrentGrid.GridSize);
                        var max = (m_gizmo.SpaceDefault.m_removeBlock.Max * CurrentGrid.GridSize);

                        Vector3 center = (min + max) * 0.5f;

                        Color color = DrawSymmetryPlane(m_symmetrySettingMode, CurrentGrid, center);

                        DrawSemiTransparentBox(CurrentGrid, m_gizmo.SpaceDefault.m_removeBlock, color.ToVector4());
                    }
                }

                if (CurrentGrid != null && (UseSymmetry || IsInSymmetrySettingMode))
                {
                    if (CurrentGrid.XSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.XSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.XSymmetryOdd ? MySymmetrySettingModeEnum.XPlaneOdd : MySymmetrySettingModeEnum.XPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.YSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.YSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.YSymmetryOdd ? MySymmetrySettingModeEnum.YPlaneOdd : MySymmetrySettingModeEnum.YPlane, CurrentGrid, center);
                    }

                    if (CurrentGrid.ZSymmetryPlane != null)
                    {
                        Vector3 center = CurrentGrid.ZSymmetryPlane.Value * CurrentGrid.GridSize;
                        DrawSymmetryPlane(CurrentGrid.ZSymmetryOdd ? MySymmetrySettingModeEnum.ZPlaneOdd : MySymmetrySettingModeEnum.ZPlane, CurrentGrid, center);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("UpdateGizmos");
            UpdateGizmos(addPos, removePos, true);

            ProfilerShort.BeginNextBlock("UpdateRenderInstanceData");
            m_renderData.UpdateRenderInstanceData();

            ProfilerShort.BeginNextBlock("CurrentVoxelBase");
            if (CurrentGrid == null || (DynamicMode && CurrentGrid != null))
            {
                MatrixD  drawMatrix = m_gizmo.SpaceDefault.m_worldMatrixAdd;
                Vector3D rotatedModelOffset;
                Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref drawMatrix, out rotatedModelOffset);
                drawMatrix.Translation = drawMatrix.Translation + rotatedModelOffset;

                m_renderData.UpdateRenderEntitiesData(drawMatrix, UseTransparency, CurrentBlockScale);
            }
            else
            {
                m_renderData.UpdateRenderEntitiesData(CurrentGrid.WorldMatrix, UseTransparency);
            }

            ProfilerShort.BeginNextBlock("UpdateBlockInfoHud");
            UpdateBlockInfoHud();
            ProfilerShort.End();
        }
Пример #11
0
        public override void UpdateBeforeSimulation()
        {
            int rayCount = 0;
            if (m_rayCastQueue.Count > 0 && m_rayCastCounter % 20 == 0)
            {
                while (rayCount < 50 && m_rayCastQueue.Count > 0)
                {
                    var rand = MyUtils.GetRandomInt(m_rayCastQueue.Count - 1);
                    var entity = m_rayCastQueue[rand].Entity;
                    var l = m_rayCastQueue[rand]._Ray;
                    var p = m_rayCastQueue[rand].Position;
                    var particle = m_rayCastQueue[rand].Particle;
                    if (entity is MyCubeGrid)
                    {
                        particle.Stop();
                        var grid = entity as MyCubeGrid;
                        var invMat = grid.PositionComp.WorldMatrixNormalizedInv;

                        if (grid.BlocksDestructionEnabled)
                        {
                            grid.Physics.ApplyDeformation(6f, 3f, 3f, Vector3.Transform(p, invMat), Vector3.Normalize(Vector3.Transform(m_directionFromSunNormalized, invMat)), MyDamageType.Environment);
                        }

                        //MyPhysics.HavokWorld.CastRay(l.From, l.To, m_hitLst);
                        //rayCount++;
                        //MyEntity ent = null;
                        //if (m_hitLst.Count != 0)
                        //    ent = m_hitLst[0].GetEntity();
                        //if (ent == grid)
                        //{
                        //    grid.Physics.ApplyDeformation(6f, 3f, 3f, Vector3.Transform(m_hitLst[0].Position, invMat), Vector3.Normalize(Vector3.Transform(m_directionFromSunNormalized, invMat)), Sandbox.Game.Weapons.MyDamageType.Environment);
                        //    //var block = grid.GetBlock(Vector3I.Floor(Vector3.Transform(m_hitLst[0].Position, invMat) / grid.GridSize));
                        //    //if (block != null)
                        //    //    grid.ApplyDestructionDeformation(block);
                        //    m_rayCastQueue.RemoveAt(0);
                        //    m_hitLst.Clear();
                        //    break;
                        //}
                        m_rayCastQueue.RemoveAt(rand);
                        m_hitLst.Clear();
                        break;
                    }
                }
            }
            m_rayCastCounter++;
            //  Update only if sun wind is active
            if (IsActive == false) return;

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

            if(MySandboxGame.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;
            }

            Vector3D campos = MySession.Static.LocalCharacter == null ? Vector3D.Zero : MySession.Static.LocalCharacter.Entity.WorldMatrix.Translation;

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

            //  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 = /*MySession.Static.Player.PlayerEntity.Entity.WorldMatrix.Translation*/ - m_directionFromSunNormalized * m_distanceToSunWind;

            Vector3D positionFront = m_positionOnCameraLine + m_directionFromSunNormalized * 2000;
            Vector3D positionBack = m_positionOnCameraLine + m_directionFromSunNormalized * -2000;

            m_planeFront = new PlaneD(positionFront, m_directionFromSunNormalized);
            m_planeBack = new PlaneD(positionBack, m_directionFromSunNormalized);

            var distanceToFrontPlane = m_planeFront.DistanceToPoint(ref campos);
            var distanceToBackPlane = m_planeBack.DistanceToPoint(ref campos);

            #region commented
            
            //Vector3 positionOfSound;
            //if ((distanceToFrontPlane <= 0) && (distanceToBackPlane >= 0))
            //{
            //    positionOfSound = MySession.Static.Player.PlayerEntity.Entity.WorldMatrix.Translation;
            //}
            //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.Static.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.Static.Player.Controller.ControlledEntity != null)
            {
                MySession.Static.PlayerShip.IncreaseHeadShake(
                    MathHelper.Lerp(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MIN,
                                    MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MAX, shake));
            }*/
            #endregion

            for (int i = 0; i < m_sunwindEntities.Count;)
			{
                if (m_sunwindEntities[i].MarkedForClose)
                {
                    m_sunwindEntities.RemoveAtFast(i);
                }
                else
                {
                    i++;
                }
            }
            var q = VRageMath.Quaternion.CreateFromRotationMatrix(Matrix.CreateFromDir(m_directionFromSunNormalized, m_downVector));
            var v = new Vector3(10000, 10000, 2000);
            MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(positionFront + m_directionFromSunNormalized * 2500, v, q), Color.Red.ToVector3(), 1, false, false);
            if (m_rayCastCounter == 120)
            {
                var pos = positionFront + m_directionFromSunNormalized * 2500;
                MyPhysics.GetPenetrationsBox(ref v, ref pos, ref q, m_intersectionLst, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                
                foreach (var hit in m_intersectionLst)
                {
                    var entity = hit.GetCollisionEntity();
                    if (entity is MyVoxelMap)
                        continue;
                    if (!m_sunwindEntities.Contains(entity))
                        m_sunwindEntities.Add(entity);
                }
                m_intersectionLst.Clear();
                for (int i = 0; i < m_sunwindEntities.Count; i++)
                {
                    var entity = m_sunwindEntities[i];
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;

                        var aabb = grid.PositionComp.WorldAABB;
                        var halfDiagonal = (aabb.Center - aabb.Min).Length();
                        var rightMax = ((aabb.Center - aabb.Min) / m_rightVector).AbsMin();
                        var downMax = ((aabb.Center - aabb.Min) / m_downVector).AbsMin();

                        var size = (grid.Max - grid.Min);
                        var max = Math.Max(size.X, Math.Max(size.Y, size.Z));
                        var invMat = grid.PositionComp.WorldMatrixNormalizedInv;

                        var start = aabb.Center - rightMax * m_rightVector - downMax * m_downVector;

                        for (int x = 0; x < rightMax * 2; x += grid.GridSizeEnum == MyCubeSize.Large ? 25 : 10)
                        {
                            for (int y = 0; y < downMax * 2; y += grid.GridSizeEnum == MyCubeSize.Large ? 25 : 10)
                            {
                                var pivot = start + x * m_rightVector + y * m_downVector;
                                pivot += (float)halfDiagonal * m_directionFromSunNormalized;
                                var circle = MyUtils.GetRandomVector3CircleNormalized();
                                float rand = MyUtils.GetRandomFloat(0, grid.GridSizeEnum == MyCubeSize.Large ? 10 : 5);
                                pivot += m_rightVector * circle.X * rand + m_downVector * circle.Z * rand;
                                LineD l = new LineD(pivot - m_directionFromSunNormalized * (float)halfDiagonal, pivot);
                                if (grid.RayCastBlocks(l.From, l.To).HasValue)
                                {
                                    l.From = pivot - m_directionFromSunNormalized * 1000;

                                    MyPhysics.CastRay(l.From, l.To, m_hitLst);
                                    m_rayCastCounter++;
                                    if (m_hitLst.Count == 0 || m_hitLst[0].HkHitInfo.GetHitEntity() != grid.Components)
                                    {
                                        m_hitLst.Clear();
                                        continue;
                                    }
                                    MyParticleEffect particle;
                                    if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Prefab_LeakingFire, out particle))
                                    {
                                        particle.WorldMatrix = MatrixD.CreateWorld(m_hitLst[0].Position, Vector3D.Forward, Vector3D.Up);
                                    }
                                    m_rayCastQueue.Add(new MyEntityRayCastPair() { Entity = grid, _Ray = l , Position = m_hitLst[0].Position, Particle = particle});
                                    //grid.Physics.ApplyDeformation(0.2f, 4, 2, Vector3.Transform(m_hitLst[0].Position, invMat), Vector3.Transform(m_directionFromSunNormalized, invMat), Sandbox.Game.Weapons.MyDamageType.Environment);
                                }
                            }
                        }
                        m_sunwindEntities.Remove(grid);
                        i--;
                    }
                    else
                    {
                        m_sunwindEntities.Remove(entity);
                        i--;
                    }

                }
                m_rayCastCounter = 0;
            }
            
            //  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();

            base.UpdateBeforeSimulation();
        }
Пример #12
0
 public static bool IsParallelTo(this Vector3D vector, PlaneD plane)
 {
     return(plane.DotNormal(vector) == 0.0d);
 }
Пример #13
0
        /// <summary>
        /// Method returns intersection point between sphere and triangle (which is defined by vertexes and plane).
        /// If no intersection found, method returns null.
        /// See below how intersection point can be calculated, because it's not so easy - for example sphere vs. triangle will 
        /// hardly generate just intersection point... more like intersection area or something.
        /// </summary>
        public static Vector3? GetSphereTriangleIntersection(ref BoundingSphereD sphere, ref PlaneD trianglePlane, ref MyTriangle_Vertices triangle)
        {
            //	Vzdialenost gule od roviny trojuholnika
            double distance;

            //	Zistim, ci sa gula nachadza pred alebo za rovinou trojuholnika, alebo ju presekava
            MySpherePlaneIntersectionEnum spherePlaneIntersection = GetSpherePlaneIntersection(ref sphere, ref trianglePlane, out distance);

            //	Ak gula presekava rovinu, tak hladam pseudo-priesecnik
            if (spherePlaneIntersection == MySpherePlaneIntersectionEnum.INTERSECTS)
            {
                //	Offset ktory pomoze vypocitat suradnicu stredu gule premietaneho na rovinu trojuholnika
                Vector3D offset = trianglePlane.Normal * distance;

                //	Priesecnik na rovine trojuholnika, je to premietnuty stred gule na rovine trojuholnika
                Vector3D intersectionPoint;
                intersectionPoint.X = sphere.Center.X - offset.X;
                intersectionPoint.Y = sphere.Center.Y - offset.Y;
                intersectionPoint.Z = sphere.Center.Z - offset.Z;

                if (GetInsidePolygonForSphereCollision(ref intersectionPoint, ref triangle))		//	Ak priesecnik nachadza v trojuholniku
                {
                    //	Toto je pripad, ked sa podarilo premietnut stred gule na rovinu trojuholnika a tento priesecnik sa
                    //	nachadza vnutri trojuholnika (tzn. sedia uhly)
                    return (Vector3)intersectionPoint;
                }
                else													//	Ak sa priesecnik nenachadza v trojuholniku, este stale sa moze nachadzat na hrane trojuholnika
                {
                    Vector3? edgeIntersection = GetEdgeSphereCollision(ref sphere.Center, (float)sphere.Radius / 1.0f, ref triangle);
                    if (edgeIntersection != null)
                    {
                        //	Toto je pripad, ked sa priemietnuty stred gule nachadza mimo trojuholnika, ale intersection gule a trojuholnika tam
                        //	je, pretoze gula presekava jednu z hran trojuholnika. Takze vratim suradnice priesecnika na jednej z hran.
                        return edgeIntersection.Value;
                    }
                }
            }

            //	Sphere doesn't collide with any triangle
            return null;
        }
Пример #14
0
 public static PlaneD FromPointNormal(Vector3D point, PlaneD normal)
 {
     return new PlaneD(normal.Normal, -point.Dot(normal.Normal));
 }
Пример #15
0
 public void InsideOrIntersectingOBBd_IsTrue(PlaneD plane, OBBd obb)
 {
     Assert.True(plane.InsideOrIntersecting(obb));
 }
Пример #16
0
 public void IntersectsAABBd_IsFalse(PlaneD plane, AABBd aabb)
 {
     Assert.False(plane.Intersects(aabb));
 }
Пример #17
0
 public static bool IsFrontFacingTo(this PlaneD plane, Vector3D direction)
 {
     return(plane.DotNormal(direction) <= 0.0d);
 }
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphereD 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 (m_boundingBox.Intersects(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 (triangleBoundingBox.Intersects(ref sphere))
                {
                    //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes triangle;
                        MyTriangle_Normals triangleNormals;
                        //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);
                        /*
                        triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0);
                        triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2);
                        triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1);
                        */
                        PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                        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.Vertices = triangle;
                                retTriangle.Normals = triangleNormals;
                          //      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);
                }
            }
        }
Пример #19
0
 public static bool EmbeddedIn(this BoundingSphereD sphere, PlaneD plane)
 {
     return(plane.Intersects(sphere) == PlaneIntersectionType.Intersecting);
 }
Пример #20
0
        public void KeepMoving(Vector3D destination, double velocity /* Meters per sec*/)
        {
            var matrix = RotorRotation.Rotor.WorldMatrix;

            // getting world points
            var rotationBasePoint = RotorRotation.Rotor.GetPosition();
            var armBasePoint      = Rotor1.Rotor.GetPosition();
            var armElbowPoint     = Rotor2.Rotor.GetPosition();
            var armTipPoint       = Tip.GetPosition();

            // adjust destination in case its something wrong with it
            var averageLength = (Vector3D.Distance(armBasePoint, armElbowPoint) + Vector3D.Distance(armElbowPoint, armTipPoint)) / 2;

            destination = CutTrailAtClosestToBase(rotationBasePoint, armTipPoint, destination);
            destination = BringToSafeZone(destination, armBasePoint, armElbowPoint, armTipPoint);
            destination = TakeNearbyPoint(destination, armTipPoint, averageLength);

            // no point doing anything if the tip is already there
            if (Vector3D.Distance(armTipPoint, destination) < DistanceToCancelMovement)
            {
                RotorRotation.Stop();
                Rotor1.Stop();
                Rotor2.Stop();
                return;
            }

            var rotationEndPoint = GetRotationEndPoint(destination, rotationBasePoint, armTipPoint);

            // calculate local points
            var localArmBasePoint     = VectorUtility.GetLocalVector(matrix, rotationBasePoint, armBasePoint);
            var localArmTipPoint      = VectorUtility.GetLocalVector(matrix, rotationBasePoint, armTipPoint);
            var localDestination      = VectorUtility.GetLocalVector(matrix, rotationBasePoint, destination);
            var localRotationEndPoint = VectorUtility.GetLocalVector(matrix, rotationBasePoint, rotationEndPoint);
            var localArmElbow         = VectorUtility.GetLocalVector(matrix, rotationBasePoint, armElbowPoint);

            var localArmPlaneNormalPoint = /*localArmBasePoint + */ Vector3D.Rotate(Rotor1.Rotor.WorldMatrix.Up, MatrixD.Transpose(matrix));

            // calculating planes to project on
            var rotationPlane = new PlaneD(Vector3D.Zero, Vector3D.UnitY); // note that rotation plane is XZ
            var armPlane      = new PlaneD(localArmBasePoint, localArmPlaneNormalPoint);

            // normalizing arm points by projecting them to the arm plane for the arm part calculations
            var normalizedArmTip      = armPlane.ProjectPoint(ref localArmTipPoint);
            var normalizedArmElbow    = armPlane.ProjectPoint(ref localArmElbow);
            var normalizedDestination = armPlane.ProjectPoint(ref localDestination);

            // calculate local projected points
            var localProjectedArmBase        = rotationPlane.ProjectPoint(ref localArmBasePoint);
            var localProjectedTip            = rotationPlane.ProjectPoint(ref normalizedArmTip);
            var localProjectedTipForRotation = rotationPlane.ProjectPoint(ref localArmTipPoint);
            var localProjectedDestination    = rotationPlane.ProjectPoint(ref localDestination); // for rotation

            // calculate rotation distance
            var rotationDistance = Math.Abs(VectorUtility.Angle(localProjectedTipForRotation, localProjectedDestination)) * localProjectedTip.Length();

            // adjust speeds
            //var rotationSpeedPart = GetRotationSpeedPart(localDestination, localArmTipPoint, localRotationBase, armDistance);
            var armDistance       = Vector3D.Distance(localDestination, localRotationEndPoint);
            var rotationSpeedPart = rotationDistance / (rotationDistance + armDistance);
            var armSpeedPart      = 1d - rotationSpeedPart;

            var rotationVelocity = rotationSpeedPart * velocity;
            var armVelocity      = armSpeedPart * velocity;

            // calculate base rotor rotation speed
            var targetRps = rotationVelocity / localProjectedTip.Length();

            // calculating tip and destination as 2D points for the arm by rotating them parallel to YZ plane
            var armBaseElevation = localArmBasePoint.Y;

            var angle2D = (float)VectorUtility.Angle(localProjectedTip - localProjectedArmBase, Vector3D.UnitX);

            if (localProjectedTip.Z < 0)
            {
                angle2D *= -1;
            }

            var armTipR         = VectorUtility.Rotate(normalizedArmTip, Vector3D.UnitY, angle2D);
            var armElbowR       = VectorUtility.Rotate(normalizedArmElbow, Vector3D.UnitY, angle2D);
            var armDestinationR = VectorUtility.Rotate(normalizedDestination, Vector3D.UnitY, angle2D);

            var armTipPoint2D         = new Vector2D(armTipR.X, armTipR.Y - armBaseElevation);
            var armElbow2D            = new Vector2D(armElbowR.X, armElbowR.Y - armBaseElevation);
            var armDestinationPoint2D = new Vector2D(armDestinationR.X, armDestinationR.Y - armBaseElevation);

            // launch movement
            MakeRotationMovement(localProjectedTipForRotation, localProjectedDestination, targetRps);
            MakeArmMovement(armTipPoint2D, armElbow2D, armDestinationPoint2D, armVelocity);
        }
Пример #21
0
 public static Vector3D ProjectOn(this Vector3D vector, PlaneD plane)
 {
     return(vector - plane.SignedDistanceTo(vector) * plane.Normal);
 }
Пример #22
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3?referenceNormalVector = null;
            float?  maxAngle = null;

            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            m_overlappedTriangles.Clear();

            // VRageRender.MyRenderProxy.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);

            // VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //VRageRender.MyRenderProxy.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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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);
                                }
                            }
                        }
                    }
                }

                //VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #23
0
 public static double SignedDistanceTo(this PlaneD plane, Vector3D point)
 {
     return(plane.DotCoordinate(point));
 }
Пример #24
0
 public PlaneSceneObject(Vector3D origin, Vector3D normal, MaterialShader shader, double radius)
     : base(origin, shader, radius)
 {
     plane = PlaneD.FromPointNormal(origin, normal);
 }
Пример #25
0
 public static double DistanceToPlaneD(PlaneD plane, Vector3D point)
 {
     return(plane.Normal.Dot(point) + plane.D);
 }
Пример #26
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, Vector3? referenceNormalVector, float? maxAngle, List<MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var aabb = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;
            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());
            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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertices triangle;
                            MyTriangle_Normals triangleNormals;
                            //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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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.Vertices = triangle;
                                    retTriangle.Normals = triangleNormals;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #27
0
 public static bool Equal(PlaneD a, PlaneD b) =>
 Equal(a.Normal, b.Normal) && Equal(a.D, b.D);
Пример #28
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, List<MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3? referenceNormalVector = null;
            float? maxAngle = null;

            var aabb = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;
            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());
            m_overlappedTriangles.Clear();

           // VRageRender.MyRenderProxy.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);
           // VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //VRageRender.MyRenderProxy.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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertices 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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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);
                                }
                            }
                        }
                    }
                }

                //VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #29
0
        public override void UpdateBeforeSimulation()
        {
            int num = 0;

            if ((m_rayCastQueue.Count > 0) && ((this.m_rayCastCounter % 20) == 0))
            {
                while ((num < 50) && (m_rayCastQueue.Count > 0))
                {
                    int                 randomInt = MyUtils.GetRandomInt(m_rayCastQueue.Count - 1);
                    MyEntity            entity    = m_rayCastQueue[randomInt].Entity;
                    MyEntityRayCastPair local1    = m_rayCastQueue[randomInt];
                    Vector3D            position  = m_rayCastQueue[randomInt].Position;
                    MyParticleEffect    particle  = m_rayCastQueue[randomInt].Particle;
                    if (entity is MyCubeGrid)
                    {
                        particle.Stop(true);
                        MyCubeGrid grid = entity as MyCubeGrid;
                        MatrixD    worldMatrixNormalizedInv = grid.PositionComp.WorldMatrixNormalizedInv;
                        if (grid.BlocksDestructionEnabled)
                        {
                            grid.Physics.ApplyDeformation(6f, 3f, 3f, (Vector3)Vector3.Transform((Vector3)position, worldMatrixNormalizedInv), Vector3.Normalize(Vector3.Transform((Vector3)m_directionFromSunNormalized, worldMatrixNormalizedInv)), MyDamageType.Environment, 0f, 0f, 0L);
                        }
                        m_rayCastQueue.RemoveAt(randomInt);
                        this.m_hitLst.Clear();
                        break;
                    }
                }
            }
            this.m_rayCastCounter++;
            if (IsActive)
            {
                float num2 = (MySandboxGame.TotalGamePlayTimeInMilliseconds - m_timeLastUpdate) / 1000f;
                m_timeLastUpdate = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                if (!MySandboxGame.IsPaused)
                {
                    m_deltaTime += num2;
                    float num3 = m_speed * m_deltaTime;
                    if (num3 >= 60000f)
                    {
                        IsActive = false;
                        StopCue();
                    }
                    else
                    {
                        Vector3D translation;
                        if (MySession.Static.LocalCharacter != null)
                        {
                            translation = MySession.Static.LocalCharacter.Entity.WorldMatrix.Translation;
                        }
                        else
                        {
                            translation = Vector3D.Zero;
                        }
                        Vector3D point = translation;
                        m_planeMiddle          = new PlaneD(m_initialSunWindPosition + (m_directionFromSunNormalized * num3), m_directionFromSunNormalized);
                        m_distanceToSunWind    = m_planeMiddle.DistanceToPoint(ref point);
                        m_positionOnCameraLine = -m_directionFromSunNormalized * m_distanceToSunWind;
                        Vector3D position = m_positionOnCameraLine + (m_directionFromSunNormalized * 2000.0);
                        Vector3D vectord3 = m_positionOnCameraLine + (m_directionFromSunNormalized * -2000.0);
                        m_planeFront = new PlaneD(position, m_directionFromSunNormalized);
                        m_planeBack  = new PlaneD(vectord3, m_directionFromSunNormalized);
                        m_planeFront.DistanceToPoint(ref point);
                        m_planeBack.DistanceToPoint(ref point);
                        int index = 0;
                        while (index < m_sunwindEntities.Count)
                        {
                            if (m_sunwindEntities[index].MarkedForClose)
                            {
                                m_sunwindEntities.RemoveAtFast <IMyEntity>(index);
                                continue;
                            }
                            index++;
                        }
                        Quaternion orientation = Quaternion.CreateFromRotationMatrix(Matrix.CreateFromDir((Vector3)m_directionFromSunNormalized, (Vector3)m_downVector));
                        Vector3    halfExtents = new Vector3(10000f, 10000f, 2000f);
                        MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(position + (m_directionFromSunNormalized * 2500.0), halfExtents, orientation), Color.Red.ToVector3(), 1f, false, false, false);
                        if (this.m_rayCastCounter == 120)
                        {
                            Vector3D translation = position + (m_directionFromSunNormalized * 2500.0);
                            MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref orientation, m_intersectionLst, 15);
                            using (List <HkBodyCollision> .Enumerator enumerator = m_intersectionLst.GetEnumerator())
                            {
                                while (enumerator.MoveNext())
                                {
                                    IMyEntity collisionEntity = enumerator.Current.GetCollisionEntity();
                                    if (!(collisionEntity is MyVoxelMap) && !m_sunwindEntities.Contains(collisionEntity))
                                    {
                                        m_sunwindEntities.Add(collisionEntity);
                                    }
                                }
                            }
                            m_intersectionLst.Clear();
                            int num6 = 0;
                            while (true)
                            {
                                if (num6 >= m_sunwindEntities.Count)
                                {
                                    this.m_rayCastCounter = 0;
                                    break;
                                }
                                IMyEntity item = m_sunwindEntities[num6];
                                if (item is MyCubeGrid)
                                {
                                    MyCubeGrid   grid2     = item as MyCubeGrid;
                                    BoundingBoxD worldAABB = grid2.PositionComp.WorldAABB;
                                    double       num7      = (worldAABB.Center - worldAABB.Min).Length();
                                    double       num8      = ((worldAABB.Center - worldAABB.Min) / m_rightVector).AbsMin();
                                    double       num9      = ((worldAABB.Center - worldAABB.Min) / m_downVector).AbsMin();
                                    Vector3I     vectori   = grid2.Max - grid2.Min;
                                    Math.Max(vectori.X, Math.Max(vectori.Y, vectori.Z));
                                    MatrixD  worldMatrixNormalizedInv = grid2.PositionComp.WorldMatrixNormalizedInv;
                                    Vector3D vectord6 = (worldAABB.Center - (num8 * m_rightVector)) - (num9 * m_downVector);
                                    int      num10    = 0;
                                    while (true)
                                    {
                                        if (num10 >= (num8 * 2.0))
                                        {
                                            m_sunwindEntities.Remove(grid2);
                                            num6--;
                                            break;
                                        }
                                        int num11 = 0;
                                        while (true)
                                        {
                                            if (num11 >= (num9 * 2.0))
                                            {
                                                num10 += (grid2.GridSizeEnum == MyCubeSize.Large) ? 0x19 : 10;
                                                break;
                                            }
                                            Vector3D to          = ((vectord6 + (num10 * m_rightVector)) + (num11 * m_downVector)) + (((float)num7) * m_directionFromSunNormalized);
                                            Vector3  vector2     = MyUtils.GetRandomVector3CircleNormalized();
                                            float    randomFloat = MyUtils.GetRandomFloat(0f, (grid2.GridSizeEnum == MyCubeSize.Large) ? ((float)10) : ((float)5));
                                            to += ((m_rightVector * vector2.X) * randomFloat) + ((m_downVector * vector2.Z) * randomFloat);
                                            LineD ed = new LineD(to - (m_directionFromSunNormalized * ((float)num7)), to);
                                            if (grid2.RayCastBlocks(ed.From, ed.To) != null)
                                            {
                                                ed.From = to - (m_directionFromSunNormalized * 1000.0);
                                                MyPhysics.CastRay(ed.From, ed.To, this.m_hitLst, 0);
                                                this.m_rayCastCounter++;
                                                if ((this.m_hitLst.Count == 0) || !ReferenceEquals(this.m_hitLst[0].HkHitInfo.GetHitEntity(), grid2.Components))
                                                {
                                                    this.m_hitLst.Clear();
                                                }
                                                else
                                                {
                                                    MyParticleEffect effect2;
                                                    MyParticlesManager.TryCreateParticleEffect("Dummy", MatrixD.CreateWorld(this.m_hitLst[0].Position, Vector3D.Forward, Vector3D.Up), out effect2);
                                                    MyEntityRayCastPair pair = new MyEntityRayCastPair {
                                                        Entity   = grid2,
                                                        _Ray     = ed,
                                                        Position = this.m_hitLst[0].Position,
                                                        Particle = effect2
                                                    };
                                                    m_rayCastQueue.Add(pair);
                                                }
                                            }
                                            num11 += (grid2.GridSizeEnum == MyCubeSize.Large) ? 0x19 : 10;
                                        }
                                    }
                                }
                                else
                                {
                                    m_sunwindEntities.Remove(item);
                                    num6--;
                                }
                                num6++;
                            }
                        }
                        if (m_distanceToSunWind <= 10000.0)
                        {
                            m_smallBillboardsStarted = true;
                        }
                        ComputeMaxDistances();
                        base.UpdateBeforeSimulation();
                    }
                }
            }
        }
Пример #30
0
 public void InsideOrIntersectingAABBd_IsTrue(PlaneD plane, AABBd aabb)
 {
     Assert.True(plane.InsideOrIntersecting(aabb));
 }
Пример #31
0
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphereD 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 (m_boundingBox.Intersects(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 (triangleBoundingBox.Intersects(ref sphere))
                {
                    //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertices triangle;
                        MyTriangle_Normals  triangleNormals;
                        //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);

                        /*
                         * triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0);
                         * triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2);
                         * triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1);
                         */
                        PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                        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.Vertices = triangle;
                                retTriangle.Normals  = triangleNormals;
                                //      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);
                }
            }
        }
Пример #32
0
        public void Normalize_Instance(PlaneD plane, PlaneD expected)
        {
            var normalizedPlane = plane.Normalize();

            Assert.Equal(normalizedPlane, expected);
        }
        // Control was picked, prepare for rotation operation
        private void PrepareRotation(Vector3D axis)
        {
            m_rotationAxis = axis;
            // Create plane for picking of rotation vectors
            m_rotationPlane = new PlaneD(m_gizmoMatrix.Translation, m_rotationAxis);
            // Set up the starting point of rotation
            m_rotationStartingPoint = m_rotationPlane.Intersection(ref m_lastRay.From, ref m_lastRay.Direction);

            // Store the transformations
            var worldMat = ControlledEntity.PositionComp.WorldMatrix;
            m_storedScale = MatrixD.CreateScale(worldMat.Scale);
            m_storedTranslation = worldMat.Translation;
            m_storedOrientation = worldMat.GetOrientation();
        }
Пример #34
0
        public override void UpdateBeforeSimulation()
        {
            int rayCount = 0;

            if (m_rayCastQueue.Count > 0 && m_rayCastCounter % 20 == 0)
            {
                while (rayCount < 50 && m_rayCastQueue.Count > 0)
                {
                    var rand     = MyUtils.GetRandomInt(m_rayCastQueue.Count - 1);
                    var entity   = m_rayCastQueue[rand].Entity;
                    var l        = m_rayCastQueue[rand].Ray;
                    var p        = m_rayCastQueue[rand].Position;
                    var particle = m_rayCastQueue[rand].Particle;
                    if (entity is MyCubeGrid)
                    {
                        particle.Stop();
                        var grid   = entity as MyCubeGrid;
                        var invMat = grid.PositionComp.GetWorldMatrixNormalizedInv();

                        if (grid.BlocksDestructionEnabled)
                        {
                            grid.Physics.ApplyDeformation(6f, 3f, 3f, Vector3.Transform(p, invMat), Vector3.Normalize(Vector3.Transform(m_directionFromSunNormalized, invMat)), MyDamageType.Environment);
                        }

                        //MyPhysics.HavokWorld.CastRay(l.From, l.To, m_hitLst);
                        //rayCount++;
                        //MyEntity ent = null;
                        //if (m_hitLst.Count != 0)
                        //    ent = m_hitLst[0].GetEntity();
                        //if (ent == grid)
                        //{
                        //    grid.Physics.ApplyDeformation(6f, 3f, 3f, Vector3.Transform(m_hitLst[0].Position, invMat), Vector3.Normalize(Vector3.Transform(m_directionFromSunNormalized, invMat)), Sandbox.Game.Weapons.MyDamageType.Environment);
                        //    //var block = grid.GetBlock(Vector3I.Floor(Vector3.Transform(m_hitLst[0].Position, invMat) / grid.GridSize));
                        //    //if (block != null)
                        //    //    grid.ApplyDestructionDeformation(block);
                        //    m_rayCastQueue.RemoveAt(0);
                        //    m_hitLst.Clear();
                        //    break;
                        //}
                        m_rayCastQueue.RemoveAt(rand);
                        m_hitLst.Clear();
                        break;
                    }
                }
            }
            m_rayCastCounter++;
            //  Update only if sun wind is active
            if (IsActive == false)
            {
                return;
            }

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

            m_timeLastUpdate = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            if (MySandboxGame.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;
            }

            Vector3D campos = MySession.LocalCharacter == null ? Vector3D.Zero : MySession.LocalCharacter.Entity.WorldMatrix.Translation;

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

            //  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 = /*MySession.Player.PlayerEntity.Entity.WorldMatrix.Translation*/ -m_directionFromSunNormalized * m_distanceToSunWind;

            Vector3D positionFront = m_positionOnCameraLine + m_directionFromSunNormalized * 2000;
            Vector3D positionBack  = m_positionOnCameraLine + m_directionFromSunNormalized * -2000;

            m_planeFront = new PlaneD(positionFront, m_directionFromSunNormalized);
            m_planeBack  = new PlaneD(positionBack, m_directionFromSunNormalized);

            var distanceToFrontPlane = m_planeFront.DistanceToPoint(ref campos);
            var distanceToBackPlane  = m_planeBack.DistanceToPoint(ref campos);

            #region commented

            //Vector3 positionOfSound;
            //if ((distanceToFrontPlane <= 0) && (distanceToBackPlane >= 0))
            //{
            //    positionOfSound = MySession.Player.PlayerEntity.Entity.WorldMatrix.Translation;
            //}
            //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.Static.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.Player.Controller.ControlledEntity != null)
             * {
             *  MySession.PlayerShip.IncreaseHeadShake(
             *      MathHelper.Lerp(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MIN,
             *                      MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_DURING_SUN_WIND_MAX, shake));
             * }*/
            #endregion

            for (int i = 0; i < m_sunwindEntities.Count;)
            {
                if (m_sunwindEntities[i].MarkedForClose)
                {
                    m_sunwindEntities.RemoveAtFast(i);
                }
                else
                {
                    i++;
                }
            }
            var q = VRageMath.Quaternion.CreateFromRotationMatrix(Matrix.CreateFromDir(m_directionFromSunNormalized, m_downVector));
            var v = new Vector3(10000, 10000, 2000);
            MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(positionFront + m_directionFromSunNormalized * 2500, v, q), Color.Red.ToVector3(), 1, false, false);
            if (m_rayCastCounter == 120)
            {
                var pos = positionFront + m_directionFromSunNormalized * 2500;
                MyPhysics.GetPenetrationsBox(ref v, ref pos, ref q, m_intersectionLst, MyPhysics.DefaultCollisionLayer);

                foreach (var hit in m_intersectionLst)
                {
                    var entity = hit.GetCollisionEntity();
                    if (entity is MyVoxelMap)
                    {
                        continue;
                    }
                    if (!m_sunwindEntities.Contains(entity))
                    {
                        m_sunwindEntities.Add(entity);
                    }
                }
                m_intersectionLst.Clear();
                for (int i = 0; i < m_sunwindEntities.Count; i++)
                {
                    var entity = m_sunwindEntities[i];
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;

                        var aabb         = grid.PositionComp.WorldAABB;
                        var halfDiagonal = (aabb.Center - aabb.Min).Length();
                        var rightMax     = ((aabb.Center - aabb.Min) / m_rightVector).AbsMin();
                        var downMax      = ((aabb.Center - aabb.Min) / m_downVector).AbsMin();

                        var size   = (grid.Max - grid.Min);
                        var max    = Math.Max(size.X, Math.Max(size.Y, size.Z));
                        var invMat = grid.PositionComp.GetWorldMatrixNormalizedInv();

                        var start = aabb.Center - rightMax * m_rightVector - downMax * m_downVector;

                        for (int x = 0; x < rightMax * 2; x += grid.GridSizeEnum == Common.ObjectBuilders.MyCubeSize.Large ? 25 : 10)
                        {
                            for (int y = 0; y < downMax * 2; y += grid.GridSizeEnum == Common.ObjectBuilders.MyCubeSize.Large ? 25 : 10)
                            {
                                var pivot = start + x * m_rightVector + y * m_downVector;
                                pivot += (float)halfDiagonal * m_directionFromSunNormalized;
                                var   circle = MyUtils.GetRandomVector3CircleNormalized();
                                float rand   = MyUtils.GetRandomFloat(0, grid.GridSizeEnum == Common.ObjectBuilders.MyCubeSize.Large ? 10 : 5);
                                pivot += m_rightVector * circle.X * rand + m_downVector * circle.Z * rand;
                                LineD l = new LineD(pivot - m_directionFromSunNormalized * (float)halfDiagonal, pivot);
                                if (grid.RayCastBlocks(l.From, l.To).HasValue)
                                {
                                    l.From = pivot - m_directionFromSunNormalized * 1000;

                                    MyPhysics.CastRay(l.From, l.To, m_hitLst);
                                    m_rayCastCounter++;
                                    if (m_hitLst.Count == 0 || m_hitLst[0].HkHitInfo.GetHitEntity() != grid.Components)
                                    {
                                        m_hitLst.Clear();
                                        continue;
                                    }
                                    MyParticleEffect particle;
                                    if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Prefab_LeakingFire, out particle))
                                    {
                                        particle.WorldMatrix = MatrixD.CreateWorld(m_hitLst[0].Position, Vector3D.Forward, Vector3D.Up);
                                    }
                                    m_rayCastQueue.Add(new MyEntityRayCastPair()
                                    {
                                        Entity = grid, Ray = l, Position = m_hitLst[0].Position, Particle = particle
                                    });
                                    //grid.Physics.ApplyDeformation(0.2f, 4, 2, Vector3.Transform(m_hitLst[0].Position, invMat), Vector3.Transform(m_directionFromSunNormalized, invMat), Sandbox.Game.Weapons.MyDamageType.Environment);
                                }
                            }
                        }
                        m_sunwindEntities.Remove(grid);
                        i--;
                    }
                    else
                    {
                        m_sunwindEntities.Remove(entity);
                        i--;
                    }
                }
                m_rayCastCounter = 0;
            }

            //  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();

            base.UpdateBeforeSimulation();
        }
        // Control was picked, prepare for drag operation
        private void PrepareDrag(Vector3D? planeNormal, Vector3D? axis)
        {
            if (axis.HasValue)
            {
                var toCameraVect = Session.Camera.Position - m_gizmoMatrix.Translation;
                var rightVect = Vector3D.Cross(axis.Value, toCameraVect);
                planeNormal = Vector3D.Cross(axis.Value, rightVect);
                // now get rid of the axis part to create perpendicular vector

                m_dragPlane = new PlaneD(m_gizmoMatrix.Translation, planeNormal.Value);
            }
            else if (planeNormal.HasValue)
            {
                m_dragPlane = new PlaneD(m_gizmoMatrix.Translation, planeNormal.Value);
            }

            m_dragStartingPoint = m_dragPlane.Intersection(ref m_lastRay.From, ref m_lastRay.Direction);
            // store axis
            if (axis != null)
            {
                m_dragAxis = axis.Value;
            }
            // Set the flag for drag in plane option.
            m_dragOverAxis = axis != null;
            // store position
            m_dragStartingPosition = ControlledEntity.PositionComp.GetPosition();
        }
        public bool Intersects(ref BoundingSphereD localSphere)
        {
            MyPrecalcComponent.AssertUpdateThread();

            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBoxD sphereBoundingBox = BoundingBoxD.CreateInvalid();
            sphereBoundingBox.Include(ref localSphere);
            Vector3I cellCoordMin, cellCoordMax;
            {
                Vector3D minD = sphereBoundingBox.Min;
                Vector3D maxD = sphereBoundingBox.Max;
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref minD, out cellCoordMin);
                MyVoxelCoordSystems.LocalPositionToGeometryCellCoord(ref maxD, out cellCoordMax);
            }

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

            MyCellCoord cell = new MyCellCoord();
            for (cell.CoordInLod.X = cellCoordMin.X; cell.CoordInLod.X <= cellCoordMax.X; cell.CoordInLod.X++)
            {
                for (cell.CoordInLod.Y = cellCoordMin.Y; cell.CoordInLod.Y <= cellCoordMax.Y; cell.CoordInLod.Y++)
                {
                    for (cell.CoordInLod.Z = cellCoordMin.Z; cell.CoordInLod.Z <= cellCoordMax.Z; cell.CoordInLod.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref localSphere) == 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 cachedData = GetCell(ref cell);

                        if (cachedData == null) continue;

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

                            MyTriangle_Vertexes triangle;
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedData.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);

                            BoundingBox localTriangleAABB = BoundingBox.CreateInvalid();
                            localTriangleAABB.Include(ref triangle.Vertex0);
                            localTriangleAABB.Include(ref triangle.Vertex1);
                            localTriangleAABB.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 (localTriangleAABB.Intersects(ref localSphere))
                            {
                                PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

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

                    }
                }
            }

            return false;
        }
Пример #37
0
 public static PlaneD FromPointNormal(Vector3D point, PlaneD normal)
 {
     return(new PlaneD(normal.Normal, -point.Dot(normal.Normal)));
 }
        //  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 BoundingSphereD sphere)
        {
            //  Check if sphere intersects bounding box of this node
            if (m_boundingBox.Intersects(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 (triangleBoundingBox.Intersects(ref sphere))
                {
                    //  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);

                    PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                    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;
        }
Пример #39
0
        /// <summary>
        /// This tells if a sphere is BEHIND, in FRONT, or INTERSECTS a plane, also it's distance
        /// </summary>
        public static MySpherePlaneIntersectionEnum GetSpherePlaneIntersection(ref BoundingSphereD sphere, ref PlaneD plane, out double distanceFromPlaneToSphere)
        {
            //  First we need to find the distance our polygon plane is from the origin.
            var planeDistance = plane.D;

            //  Here we use the famous distance formula to find the distance the center point
            //  of the sphere is from the polygon's plane.
            distanceFromPlaneToSphere = (plane.Normal.X * sphere.Center.X + plane.Normal.Y * sphere.Center.Y + plane.Normal.Z * sphere.Center.Z + planeDistance);

            //  If the absolute value of the distance we just found is less than the radius,
            //  the sphere intersected the plane.
            if (Math.Abs(distanceFromPlaneToSphere) < sphere.Radius)
            {
                return(MySpherePlaneIntersectionEnum.INTERSECTS);
            }
            else if (distanceFromPlaneToSphere >= sphere.Radius)
            {
                //  Else, if the distance is greater than or equal to the radius, the sphere is
                //  completely in FRONT of the plane.
                return(MySpherePlaneIntersectionEnum.FRONT);
            }

            //  If the sphere isn't intersecting or in FRONT of the plane, it must be BEHIND
            return(MySpherePlaneIntersectionEnum.BEHIND);
        }
Пример #40
0
        /// <summary>
        /// Method returns intersection point between sphere and triangle (which is defined by vertexes and plane).
        /// If no intersection found, method returns null.
        /// See below how intersection point can be calculated, because it's not so easy - for example sphere vs. triangle will
        /// hardly generate just intersection point... more like intersection area or something.
        /// </summary>
        public static Vector3?GetSphereTriangleIntersection(ref BoundingSphereD sphere, ref PlaneD trianglePlane, ref MyTriangle_Vertices triangle)
        {
            //	Vzdialenost gule od roviny trojuholnika
            double distance;

            //	Zistim, ci sa gula nachadza pred alebo za rovinou trojuholnika, alebo ju presekava
            MySpherePlaneIntersectionEnum spherePlaneIntersection = GetSpherePlaneIntersection(ref sphere, ref trianglePlane, out distance);

            //	Ak gula presekava rovinu, tak hladam pseudo-priesecnik
            if (spherePlaneIntersection == MySpherePlaneIntersectionEnum.INTERSECTS)
            {
                //	Offset ktory pomoze vypocitat suradnicu stredu gule premietaneho na rovinu trojuholnika
                Vector3D offset = trianglePlane.Normal * distance;

                //	Priesecnik na rovine trojuholnika, je to premietnuty stred gule na rovine trojuholnika
                Vector3D intersectionPoint;
                intersectionPoint.X = sphere.Center.X - offset.X;
                intersectionPoint.Y = sphere.Center.Y - offset.Y;
                intersectionPoint.Z = sphere.Center.Z - offset.Z;

                if (GetInsidePolygonForSphereCollision(ref intersectionPoint, ref triangle))            //	Ak priesecnik nachadza v trojuholniku
                {
                    //	Toto je pripad, ked sa podarilo premietnut stred gule na rovinu trojuholnika a tento priesecnik sa
                    //	nachadza vnutri trojuholnika (tzn. sedia uhly)
                    return((Vector3)intersectionPoint);
                }
                else                                                                                                    //	Ak sa priesecnik nenachadza v trojuholniku, este stale sa moze nachadzat na hrane trojuholnika
                {
                    Vector3?edgeIntersection = GetEdgeSphereCollision(ref sphere.Center, (float)sphere.Radius / 1.0f, ref triangle);
                    if (edgeIntersection != null)
                    {
                        //	Toto je pripad, ked sa priemietnuty stred gule nachadza mimo trojuholnika, ale intersection gule a trojuholnika tam
                        //	je, pretoze gula presekava jednu z hran trojuholnika. Takze vratim suradnice priesecnika na jednej z hran.
                        return(edgeIntersection.Value);
                    }
                }
            }

            //	Sphere doesn't collide with any triangle
            return(null);
        }
Пример #41
0
 public PlaneSceneObject(Vector3D origin, Vector3D normal, MaterialShader shader, double radius)
     : base(origin, shader, radius)
 {
     plane = PlaneD.FromPointNormal(origin, normal);
 }