Example #1
1
 public BlockUpdate( Player origin, Vector3I coord, Block blockType ) {
     Origin = origin;
     X = (short)coord.X;
     Y = (short)coord.Y;
     Z = (short)coord.Z;
     BlockType = blockType;
 }
Example #2
0
        public override bool Prepare(Vector3I[] marks)
        {
            a = marks[0];
            c = marks[1];
            b = marks[2];

            d = new Vector3I(a.X + c.X - b.X, a.Y + c.Y - b.Y, a.Z + c.Z - b.Z);

            Bounds = new BoundingBox(
                Math.Min(Math.Min(a.X, b.X), Math.Min(c.X, d.X)),
                Math.Min(Math.Min(a.Y, b.Y), Math.Min(c.Y, d.Y)),
                Math.Min(Math.Min(a.Z, b.Z), Math.Min(c.Z, d.Z)),
                Math.Max(Math.Max(a.X, b.X), Math.Max(c.X, d.X)),
                Math.Max(Math.Max(a.Y, b.Y), Math.Max(c.Y, d.Y)),
                Math.Max(Math.Max(a.Z, b.Z), Math.Max(c.Z, d.Z))
            );

            Coords = Bounds.MinVertex;

            if (!base.Prepare(marks))
                return false;

            normal = (b - a).Cross(c - a);
            normalF = normal.Normalize();
            BlocksTotalEstimate = GetBlockTotalEstimate();

            s1 = normal.Cross(a - b).Normalize();
            s2 = normal.Cross(b - c).Normalize();
            s3 = normal.Cross(c - d).Normalize();
            s4 = normal.Cross(d - a).Normalize();

            return true;
        }
            public VoxelChunk(Vector3I coords)
            {
                Coords = coords;

                Material = new byte[TotalVolume];
                Content = new byte[TotalVolume];
            }
Example #4
0
 public static void Plant( [NotNull] ForesterArgs args, Vector3I treeCoordinate ) {
     List<Tree> treeList = new List<Tree> {
         new Tree {
             Args = args,
             Height = args.Height,
             Pos = treeCoordinate
         }
     };
     switch( args.Shape ) {
         case TreeShape.Rainforest:
             PlantRainForestTrees( args, treeList );
             break;
         case TreeShape.Mangrove:
             PlantMangroves( args, treeList );
             break;
         default:
             PlantTrees( args, treeList );
             break;
     }
     ProcessTrees( args, treeList );
     if( args.Foliage ) {
         foreach( Tree tree in treeList ) {
             tree.MakeFoliage();
         }
     }
     if( args.Wood ) {
         foreach( Tree tree in treeList ) {
             tree.MakeTrunk();
         }
     }
 }
Example #5
0
        public override bool Prepare( Vector3I[] marks )
        {
            if( Player.World == null ) PlayerOpException.ThrowNoWorld( Player );
            if( !base.Prepare( marks ) ) return false;

            BlocksTotalEstimate = Bounds.Volume;
            Coords = Bounds.MinVertex;

            // remember dimensions and orientation
            CopyState copyInfo = new CopyState( marks[0], marks[1] );

            for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) {
                for( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) {
                    for( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) {
                        copyInfo.Buffer[x - Bounds.XMin, y - Bounds.YMin, z - Bounds.ZMin] = Map.GetBlock( x, y, z );
                    }
                }
            }
            copyInfo.OriginWorld = Player.World.Name;
            copyInfo.CopyTime = DateTime.UtcNow;
            Player.SetCopyInformation( copyInfo );

            Player.Message( "{0} blocks cut into slot #{1}. You can now &H/Paste",
                            Bounds.Volume, Player.CopySlot + 1 );
            Player.Message( "Origin at {0} {1}{2} corner.",
                            (copyInfo.Orientation.X == 1 ? "bottom" : "top"),
                            (copyInfo.Orientation.Y == 1 ? "south" : "north"),
                            (copyInfo.Orientation.Z == 1 ? "east" : "west") );

            Context |= BlockChangeContext.Cut;
            return true;
        }
 public static void WorldPositionToRenderCellCoord(int lod, Vector3D referenceVoxelMapPosition, ref Vector3D worldPosition, out Vector3I renderCellCoord)
 {
     Vector3D tmp;
     WorldPositionToLocalPosition(referenceVoxelMapPosition, ref worldPosition, out tmp);
     tmp /= RenderCellSizeInMeters(lod);
     Vector3I.Floor(ref tmp, out renderCellCoord);
 }
        public void BreakBlockEffect( Vector3I position, byte block )
        {
            Vector3 startPos = new Vector3( position.X, position.Y, position.Z );
            int texLoc = game.BlockInfo.GetTextureLoc( block, TileSide.Left );
            TextureRec rec = game.TerrainAtlas.GetTexRec( texLoc );

            float invSize = TerrainAtlas2D.invElementSize;
            int cellsCountX = (int)( 0.25f / invSize );
            int cellsCountY = (int)( 0.25f / invSize );
            float elementXSize = invSize * 0.25f;
            float elementYSize = invSize * 0.25f;

            Random rnd = new Random();
            for( int i = 0; i < 25; i++ ) {
                double velX = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/;
                double velZ = ( rnd.NextDouble() * 0.8/*5*/ ) - 0.4/*0.25*/;
                double velY = ( rnd.NextDouble() + 0.25 ) * game.BlockInfo.Height[block];
                Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ );
                double xOffset = rnd.NextDouble() - 0.125;
                double yOffset = rnd.NextDouble() - 0.125;
                double zOffset = rnd.NextDouble() - 0.125;
                Vector3 pos = startPos + new Vector3( (float)xOffset, (float)yOffset, (float)zOffset );
                TextureRec particleRec = rec;
                particleRec.U1 = (float)( rec.U1 + rnd.Next( 0, cellsCountX ) * elementXSize );
                particleRec.V1 = (float)( rec.V1 + rnd.Next( 0, cellsCountY ) * elementYSize );
                particleRec.U2 = particleRec.U1 + elementXSize;
                particleRec.V2 = particleRec.V1 + elementYSize;
                double life = 1.5 - rnd.NextDouble();

                particles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) );
            }
        }
        public override bool Prepare( Vector3I[] marks ) {
            if( !base.Prepare( marks ) ) return false;

            double rx = Bounds.Width / 2d;
            double ry = Bounds.Length / 2d;
            double rz = Bounds.Height / 2d;

            radius.X = (float)(1 / (rx * rx));
            radius.Y = (float)(1 / (ry * ry));
            radius.Z = (float)(1 / (rz * rz));

            center.X = (Bounds.XMin + Bounds.XMax) / 2f;
            center.Y = (Bounds.YMin + Bounds.YMax) / 2f;
            center.Z = (Bounds.ZMin + Bounds.ZMax) / 2f;

            fillInner = Brush.AlternateBlocks > 1 &&
                        Bounds.Width > 2 &&
                        Bounds.Length > 2 &&
                        Bounds.Height > 2;

            Coords = Bounds.MinVertex;

            if( fillInner ) {
                BlocksTotalEstimate = (int)(4 / 3d * Math.PI * rx * ry * rz);
            } else {
                // rougher estimation than the non-hollow form, a voxelized surface is a bit funky
                BlocksTotalEstimate = (int)(4 / 3d * Math.PI * ((rx + .5) * (ry + .5) * (rz + .5) -
                                                                (rx - .5) * (ry - .5) * (rz - .5)) * 0.85);
            }
            return true;
        }
Example #9
0
 public CopyState( Vector3I mark1, Vector3I mark2 ) {
     BoundingBox box = new BoundingBox( mark1, mark2 );
     Orientation = new Vector3I( mark1.X <= mark2.X ? 1 : -1,
                                 mark1.Y <= mark2.Y ? 1 : -1,
                                 mark1.Z <= mark2.Z ? 1 : -1 );
     Buffer = new Block[box.Width, box.Length, box.Height];
 }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var ob = builder as MyObjectBuilder_MultiBlockDefinition;
            MyDebug.AssertDebug(ob != null);

            if (ob.BlockDefinitions != null && ob.BlockDefinitions.Length > 0)
            {
                MinPosition = Vector3I.MaxValue;
                MaxPosition = Vector3I.MinValue;

                BlockDefinitions = new MyMultiBlockPartDefinition[ob.BlockDefinitions.Length];
                for (int i = 0; i < ob.BlockDefinitions.Length; ++i)
                {
                    BlockDefinitions[i] = new MyMultiBlockPartDefinition();

                    var obBlockDef = ob.BlockDefinitions[i];
                    BlockDefinitions[i].Id = obBlockDef.Id;
                    BlockDefinitions[i].Position = obBlockDef.Position;
                    BlockDefinitions[i].Forward = obBlockDef.Orientation.Forward;
                    BlockDefinitions[i].Up = obBlockDef.Orientation.Up;

                    MinPosition = Vector3I.Min(MinPosition, obBlockDef.Position);
                    MaxPosition = Vector3I.Max(MaxPosition, obBlockDef.Position);
                }
            }
        }
Example #11
0
        /// <summary>
        /// Copies part of skeleton to other skeleton, both positions are inclusive
        /// </summary>
        public void CopyTo(MyGridSkeleton target, Vector3I fromGridPosition, Vector3I toGridPosition)
        {
            Vector3I baseBonePos = fromGridPosition * BoneDensity;
            Vector3I max = (toGridPosition - fromGridPosition + Vector3I.One) * BoneDensity;
            Vector3I boneOffset;
            for (boneOffset.X = 0; boneOffset.X <= max.X; boneOffset.X++)
            {
                for (boneOffset.Y = 0; boneOffset.Y <= max.Y; boneOffset.Y++)
                {
                    for (boneOffset.Z = 0; boneOffset.Z <= max.Z; boneOffset.Z++)
                    {
                        Vector3I bonePos = baseBonePos + boneOffset;

                        Vector3 bone;
                        if (Bones.TryGetValue(bonePos, out bone))
                        {
                            target.Bones[bonePos] = bone;
                        }
                        else
                        {
                            target.Bones.Remove(bonePos);
                        }
                    }
                }
            }
        }
Example #12
0
 public static Direction GetDirection(Vector3I[] marks)
 {
     if (Math.Abs(marks[1].X - marks[0].X) > Math.Abs(marks[1].Y - marks[0].Y))
     {
         if (marks[0].X < marks[1].X)
         {
             return Direction.one;
         }
         else
         {
             return Direction.two;
         }
     }
     else if (Math.Abs(marks[1].X - marks[0].X) < Math.Abs(marks[1].Y - marks[0].Y))
     {
         if (marks[0].Y < marks[1].Y)
         {
             return Direction.three;
         }
         else
         {
             return Direction.four;
         }
     }
     else
         return Direction.Null;
 }
Example #13
0
        public override bool Prepare( Vector3I[] marks )
        {
            if ( !base.Prepare( marks ) )
                return false;

            // center of the torus
            center = marks[0];

            Vector3I radiusVector = ( marks[1] - center ).Abs();

            // tube radius is figured out from Z component of the mark vector
            tubeR = radiusVector.Z;

            // torus radius is figured out from length of vector's X-Y components
            bigR = Math.Sqrt( radiusVector.X * radiusVector.X +
                              radiusVector.Y * radiusVector.Y + .5 );

            // tube + torus radius, rounded up. This will be the maximum extend of the torus.
            int combinedRadius = ( int )Math.Ceiling( bigR + tubeR );

            // vector from center of torus to the furthest-away point of the bounding box
            Vector3I combinedRadiusVector = new Vector3I( combinedRadius, combinedRadius, tubeR + 1 );

            // adjusted bounding box
            Bounds = new BoundingBox( center - combinedRadiusVector, center + combinedRadiusVector );

            BlocksTotalEstimate = ( int )( 2 * Math.PI * Math.PI * bigR * ( tubeR * tubeR + Bias ) );

            coordEnumerator = BlockEnumerator().GetEnumerator();
            return true;
        }
        internal MyVoxelPhysicsBody(MyVoxelBase voxelMap, float phantomExtend, float predictionSize = 3.0f, bool lazyPhysics = false)
            : base(voxelMap, RigidBodyFlag.RBF_STATIC)
        {
            ProfilerShort.Begin("MyVoxelPhysicsBody(");

            InvalidCells = new HashSet<Vector3I>[2];

            InvalidCells[0] = new HashSet<Vector3I>();
            InvalidCells[1] = new HashSet<Vector3I>();

            m_predictionSize = predictionSize;
            m_phantomExtend = phantomExtend;
            m_voxelMap = voxelMap;
            Vector3I storageSize = m_voxelMap.Size;
            Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;

            if (!MyFakes.ENABLE_LAZY_VOXEL_PHYSICS || !lazyPhysics || !ENABLE_AABB_PHANTOM)
            {
                CreateRigidBodies();
            }

            ProfilerShort.End();

            MaterialType = MyMaterialType.ROCK;
        }
 private void AssertRangeIsInside(int lodIndex, ref Vector3I globalMin, ref Vector3I globalMax)
 {
     var leafMinInLod = m_leafMin >> lodIndex;
     var leafMaxInLod = m_leafMax >> lodIndex;
     Debug.Assert(globalMin.IsInsideInclusive(ref leafMinInLod, ref leafMaxInLod));
     Debug.Assert(globalMax.IsInsideInclusive(ref leafMinInLod, ref leafMaxInLod));
 }
 public MyProviderLeaf(IMyStorageDataProvider provider, MyStorageDataTypeEnum dataType, ref Vector3I leafMin, ref Vector3I leafMax)
 {
     m_provider = provider;
     m_dataType = dataType;
     m_leafMin = leafMin;
     m_leafMax = leafMax;
 }
        void ModAPI.Interfaces.IMyStorage.ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex,  Vector3I lodVoxelRangeMin,  Vector3I lodVoxelRangeMax)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
                return;

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
        }
Example #18
0
 public UndoBlock( Vector3I coord, Block block )
 {
     X = (short)coord.X;
     Y = (short)coord.Y;
     Z = (short)coord.Z;
     Block = block;
 }
Example #19
0
 public SandTask( World world, Vector3I position, Block Type )
     : base(world)
 {
     _pos = position;
     _nextPos = position.Z - 1;
     _type = Type;
 }
        internal MyVoxelPhysicsBody(MyVoxelMap voxelMap): base(voxelMap, RigidBodyFlag.RBF_STATIC)
        {
            m_voxelMap = voxelMap;
            Vector3I storageSize = m_voxelMap.Size;
            Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;

            HkUniformGridShape shape = new HkUniformGridShape(
                new HkUniformGridShapeArgs()
                {
                    CellsCount = numCels,
                    CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES,
                    CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF,
                    CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                });
            shape.SetShapeRequestHandler(RequestShapeBlocking);

            CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.StaticCollisionLayer);
            shape.Base.RemoveReference();

            if (ENABLE_AABB_PHANTOM)
            {
                m_aabbPhantom = new Havok.HkpAabbPhantom(new BoundingBox(Vector3.Zero, m_voxelMap.SizeInMetres), 0);
                m_aabbPhantom.CollidableAdded = AabbPhantom_CollidableAdded;
                m_aabbPhantom.CollidableRemoved = AabbPhantom_CollidableRemoved;
            }

            if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION)
                Friction = 0.65f;

            MaterialType = Sandbox.Common.MyMaterialType.ROCK;
        }
Example #21
0
 public FireworkParticle(World world, Vector3I pos, Block block)
     : base(world)
 {
     _startingPos = pos;
     _nextZ = pos.Z - 1;
     _block = block;
 }
        static DeformationTable CreateTable(Vector3I normal)
        {
            DeformationTable result = new DeformationTable();
            result.Normal = normal;

            Vector3I centerBone = new Vector3I(1, 1, 1);
            var absNormal = Vector3I.Abs(normal);
            var mask = new Vector3I(1, 1, 1) - absNormal;
            mask *= 2;

            for (int x = -mask.X; x <= mask.X; x++)
            {
                for (int y = -mask.Y; y <= mask.Y; y++)
                {
                    for (int z = -mask.Z; z <= mask.Z; z++)
                    {
                        var offset = new Vector3I(x, y, z);

                        float maxOffset = Math.Max(Math.Abs(z), Math.Max(Math.Abs(x), Math.Abs(y)));
                        float ratio = 1;
                        if (maxOffset > 1)
                            ratio = 0.3f;

                        float moveDist = ratio * MyGridConstants.DEFORMATION_TABLE_BASE_MOVE_DIST;
                        Vector3I offsetA = centerBone + new Vector3I(x, y, z) + normal;
                        result.OffsetTable.Add(offsetA, -normal * moveDist);

                        result.MinOffset = Vector3I.Min(result.MinOffset, offset);
                        result.MaxOffset = Vector3I.Max(result.MaxOffset, offset);
                    }
                }
            }
            return result;
        }
        public override void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, float lodVoxelSizeHalf)
        {
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            byte defaultMaterial = m_material.Index;

            Vector3I v = new Vector3I();
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        var write = v - minInLod + writeOffset;

                        byte slope = target.Material(ref write);
                        if (slope == 0) continue;

                        Vector3 localPos = v * lodVoxelSize;

                        var mat = GetMaterialForPosition(ref localPos, lodVoxelSize);
                        target.Material(ref write, mat.Index);
                    }
                }
            }
        }
		public override void Unregister(MyEntity entity, Vector3I forwardVector)
		{
			base.Unregister(entity, forwardVector);
			var thrust = entity as MyThrust;
			if (thrust == null)
				return;

			thrust.EnabledChanged -= thrust_EnabledChanged;
			thrust.SlimBlock.ComponentStack.IsFunctionalChanged -= ComponentStack_IsFunctionalChanged;

            // Need to recalculate the slowdown factor. Maybe save different levels of the factors and just revert back to previous one
		    SlowdownFactor = 0f;
		    foreach (var direction in Base6Directions.IntDirections)
		    {
		        foreach (var dataByType in m_dataByFuelType)
		        {
		            foreach (var entityInDirection in dataByType.ThrustsByDirection[direction])
		            {
		                var thrustInDirection = entityInDirection as MyThrust;
		                if (thrustInDirection == null)
		                    continue;

		                SlowdownFactor = Math.Max(thrustInDirection.BlockDefinition.SlowdownFactor, SlowdownFactor);
		            }
		        }
		    }
		}
Example #25
0
 public BlockFloat(World world, Vector3I position, Block Type)
     : base(world)
 {
     _pos = position;
     _nextPos = position.Z + 1;
     type = Type;
 }
Example #26
0
 public override bool Prepare( Vector3I[] marks )
 {
     if( !base.Prepare( marks ) ) return false;
     BlocksTotalEstimate = Bounds.Volume;
     Coords = Bounds.MinVertex;
     return true;
 }
 public void AddSelection( byte id, Vector3I p1, Vector3I p2, FastColour col )
 {
     RemoveSelection( id );
     SelectionBox selection = new SelectionBox( p1, p2, col );
     selection.ID = id;
     selections.Add( selection );
 }
 public static void WorldPositionToRenderCellCoord(Vector3D referenceVoxelMapPosition, ref Vector3D worldPosition, out Vector3I renderCellCoord)
 {
     Vector3D tmp;
     WorldPositionToLocalPosition(referenceVoxelMapPosition, ref worldPosition, out tmp);
     tmp /= MyVoxelConstants.RENDER_CELL_SIZE_IN_METRES;
     Vector3I.Floor(ref tmp, out renderCellCoord);
 }
Example #29
0
        /// <summary>
        /// Executes the drawer on a separate thread. The bool is there if the user finds a need to stop the drawing.
        /// (This happens when CancelDrawer() is called.)
        /// </summary>
        public void Start(ClassicBot main, ref bool Aborted, Vector3I[] points, byte blocktype, ref int sleeptime)
        {
            Vector3I Coords = Vector3I.Min(points[0], points[1]);
            Vector3I MinVertex = Vector3I.Min(points[0], points[1]);
            Vector3I MaxVertex = Vector3I.Max(points[0], points[1]);
            double rx = (MaxVertex.X - MinVertex.X + 1) / 2d;
            double ry = (MaxVertex.Y - MinVertex.Y + 1) / 2d;
            double rz = (MaxVertex.Z - MinVertex.Z + 1) / 2d;

            radius.X = (float)(1 / (rx * rx));
            radius.Y = (float)(1 / (ry * ry));
            radius.Z = (float)(1 / (rz * rz));

            // find center points
            center.X = (float)((MinVertex.X + MaxVertex.X) / 2d);
            center.Y = (float)((MinVertex.Y + MaxVertex.Y) / 2d);
            center.Z = (float)((MinVertex.Z + MaxVertex.Z) / 2d);

            Coords = MinVertex;
            main.SendPositionPacket((short)Coords.X, (short)Coords.Y, (short)Coords.Z);
            IEnumerator<Vector3I> coordEnumerator = BlockEnumerator(MinVertex, MaxVertex).GetEnumerator();
            while(coordEnumerator.MoveNext())
            {
                if (Aborted == true) {
                    return;
                }
                Thread.Sleep(sleeptime);
                Coords = coordEnumerator.Current;
                main.SendPositionPacket((short)Coords.X, (short)Coords.Y, (short)Coords.Z);
                main.SendBlockPacket((short)Coords.X, (short)Coords.Y, (short)Coords.Z, 1, blocktype);

            }
            main.SetDrawerToNull();
        }
Example #30
0
        IEnumerable<Vector3I> BlockEnumerator(Vector3I min, Vector3I max)
        {
            for( int x = min.X; x <= max.X; x++ ) {
                for( int y = min.Y; y <= max.Y; y++ ) {
                    yield return new Vector3I( x, y, min.Z );
                    if( min.Z != max.Z ) {
                        yield return new Vector3I( x, y, max.Z );
                    }
                }
            }

            if((max.Z - min.Z + 1) > 2) {
                for( int x = min.X; x <= max.X; x++ ) {
                    for( int z = min.Z + 1; z < max.Z; z++ ) {
                        yield return new Vector3I( x, min.Y, z );
                        if( min.Y != max.Y ) {
                            yield return new Vector3I( x, max.Y, z );
                        }
                    }
                }

                for( int y = min.Y + 1; y < max.Y; y++ ) {
                    for( int z = min.Z + 1; z < max.Z; z++ ) {
                        yield return new Vector3I( min.X, y, z );
                        if( min.X != max.X ) {
                            yield return new Vector3I( max.X, y, z );
                        }
                    }
                }
            }
        }
Example #31
0
        /// <summary>
        /// Adds environment item to internal collections. Creates render and physics data.
        /// </summary>
        /// <returns>True if successfully added, otherwise false.</returns>
        private bool AddItem(MyEnvironmentItemDefinition itemDefinition, ref MatrixD worldMatrix, ref BoundingBoxD aabbWorld,
                             HkStaticCompoundShape sectorRootShape, Dictionary <MyStringId, HkShape> subtypeIdToShape)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
            {
                return(true);
            }

            Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition),
                         String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id));
            if (!m_definition.ContainsItemDefinition(itemDefinition))
            {
                return(false);
            }

            //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString());

            MyModel model = MyModels.GetModelOnlyData(itemDefinition.Model);

            if (model == null)
            {
                //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id));
                return(false);
            }

            int localId = worldMatrix.Translation.GetHashCode();

            MyEnvironmentItemData data = new MyEnvironmentItemData()
            {
                Id               = localId,
                SubtypeId        = itemDefinition.Id.SubtypeId,
                Transform        = new MyTransformD(ref worldMatrix),
                Enabled          = true,
                SectorInstanceId = -1
            };

            //Preload split planes
            //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName);

            aabbWorld.Include(model.BoundingBox.Transform(worldMatrix));

            CheckModelConsistency(itemDefinition);

            MatrixD transform = data.Transform.TransformMatrix;

            Vector3I            sectorId = MyEnvironmentSector.GetSectorId(transform.Translation, m_definition.SectorSize);
            MyEnvironmentSector sector;

            if (!m_sectors.TryGetValue(sectorId, out sector))
            {
                sector = new MyEnvironmentSector(sectorId);
                m_sectors.Add(sectorId, sector);
            }

            // Adds instance of the given model. Local matrix specified might be changed internally in renderer.
            Matrix transformL = (Matrix)transform;

            data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance);

            int physicsShapeInstanceId;

            if (AddPhysicsShape(data.SubtypeId, model, ref transform, sectorId, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId))
            {
                // Map to data index - note that itemData is added after this to its list!
                m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = localId;
                m_localIdToPhysicsShapeInstanceId[localId] = physicsShapeInstanceId;
            }

            data.Transform = new MyTransformD(transform);

            if (m_itemsData.ContainsKey(localId))
            {
                Debug.Fail("More items on same place! " + transform.Translation.ToString());
            }
            else
            {
                m_itemsData.Add(localId, data);
            }

            return(true);
        }
Example #32
0
 public bool CanPlaceTile(Entity entity, Vector3I location, Tile tile, TileAccessFlags accessFlags)
 {
     return(true);
 }
Example #33
0
        public bool AddMaterial(int materialId, int amount, Vector3I globalPosition)
        {
            bool success = false;

            if (amount > 0)
            {
                Vector3I chunkPosition = CalculateChunkPosition(globalPosition);
                Vector3I voxelPosition = CalculateVoxelPositionInChunk(globalPosition, chunkPosition);

                bool existsBefore = _chunks[chunkPosition][voxelPosition].Exists;

                if (_chunks[chunkPosition][voxelPosition].Amount + amount <= Constant.MaxMaterialAmount)
                {
                    IList <(Vector3I ChunkPosition, Vector3I VoxelPosition)> positions =
                        CalculateVoxelPositions(globalPosition);

                    if (_chunks[chunkPosition][voxelPosition].MaterialId == Constant.MaterialAir)
                    {
                        foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in positions)
                        {
                            _chunks[position.ChunkPosition][position.VoxelPosition].MaterialId = materialId;
                        }
                    }
                    if (_chunks[chunkPosition][voxelPosition].MaterialId == materialId)
                    {
                        foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in positions)
                        {
                            _chunks[position.ChunkPosition][position.VoxelPosition].AddMaterial(amount);
                            if (!_updatedChunkCoordinates.Contains(position.ChunkPosition))
                            {
                                _updatedChunkCoordinates.Add(position.ChunkPosition);
                            }
                        }

                        //Update NeighborChunk if neccessairy
                        foreach (Vector3I neighborPosition in GetNeighbors(globalPosition))
                        {
                            if (PositionIsInsideWorld(neighborPosition))
                            {
                                IList <(Vector3I ChunkPosition, Vector3I VoxelPosition)> neighborPositions =
                                    CalculateVoxelPositions(neighborPosition);
                                foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in neighborPositions)
                                {
                                    if (!_updatedChunkCoordinates.Contains(position.ChunkPosition))
                                    {
                                        _updatedChunkCoordinates.Add(position.ChunkPosition);
                                    }
                                }
                            }
                        }

                        success = true;
                    }
                }

                if (!existsBefore && _chunks[chunkPosition][voxelPosition].Exists)
                {
                    _chunks[chunkPosition].UsedVoxelAmount++;
                    DecrementNeighborsEmptyNeighborCount(globalPosition);
                }
            }

            return(success);
        }
Example #34
0
        private Vector3I CalculateVoxelPositionInChunk(Vector3I globalPosition, Vector3I chunkPosition)
        {
            Vector3I voxelInChunkPosition = globalPosition - (chunkPosition * Constant.ChunkSize);

            return(voxelInChunkPosition);
        }
Example #35
0
        private IList <(Vector3I ChunkPosition, Vector3I VoxelPosition)> CalculateVoxelPositions(Vector3I globalPosition)
        {
            List <(Vector3I ChunkPosition, Vector3I VoxelPosition)> positions = new List <(Vector3I ChunkPosition, Vector3I VoxelPosition)>();

            Vector3I chunkPosition = CalculateChunkPosition(globalPosition);
            Vector3I voxelPosition = CalculateVoxelPositionInChunk(globalPosition, chunkPosition);

            positions.Add((chunkPosition, voxelPosition));

            Vector3I afterChunkPosition;
            Vector3I afterVoxelPosition;

            if (voxelPosition.X == 0 && ChunkIsInsideWorld((chunkPosition - new Vector3I(1, 0, 0))))
            {
                foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in positions.ToArray())
                {
                    afterChunkPosition   = position.ChunkPosition - new Vector3I(1, 0, 0);
                    afterVoxelPosition   = position.VoxelPosition;
                    afterVoxelPosition.X = Constant.ChunkSizeX;
                    positions.Add((afterChunkPosition, afterVoxelPosition));
                }
            }
            if (voxelPosition.Y == 0 && ChunkIsInsideWorld((chunkPosition - new Vector3I(0, 1, 0))))
            {
                foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in positions.ToArray())
                {
                    afterChunkPosition   = position.ChunkPosition - new Vector3I(0, 1, 0);
                    afterVoxelPosition   = position.VoxelPosition;
                    afterVoxelPosition.Y = Constant.ChunkSizeY;
                    positions.Add((afterChunkPosition, afterVoxelPosition));
                }
            }
            if (voxelPosition.Z == 0 && ChunkIsInsideWorld((chunkPosition - new Vector3I(0, 0, 1))))
            {
                foreach ((Vector3I ChunkPosition, Vector3I VoxelPosition)position in positions.ToArray())
                {
                    afterChunkPosition   = position.ChunkPosition - new Vector3I(0, 0, 1);
                    afterVoxelPosition   = position.VoxelPosition;
                    afterVoxelPosition.Z = Constant.ChunkSizeZ;
                    positions.Add((afterChunkPosition, afterVoxelPosition));
                }
            }

            return(positions);
        }
Example #36
0
        public bool RaytraceEmptyOnFilledVoxel(Vector3 rayPosition, Vector3 rayDirection, out Vector3I voxelPosition)
        {
            bool success = _voxelMarcher.InitializeStartPosition(rayPosition, rayDirection);

            voxelPosition = new Vector3I(-1);

            bool emptySet = false;

            while (success && !PositionIsUnderWorld(_voxelMarcher.VoxelPosition) && GetVoxel(_voxelMarcher.VoxelPosition).IsEmpty)
            {
                emptySet      = true;
                voxelPosition = _voxelMarcher.VoxelPosition;

                success = _voxelMarcher.CalculateNextPosition();
            }
            if (!(success && emptySet && (PositionIsUnderWorld(_voxelMarcher.VoxelPosition) ||
                                          !GetVoxel(_voxelMarcher.VoxelPosition).IsEmpty)))
            {
                success = false;
            }
            return(success);
        }
Example #37
0
        /// <summary>
        /// Adds item physics shape to rootShape and returns instance id of added shape instance.
        /// </summary>
        /// <returns>true if ite physics shape has been added, otherwise false.</returns>
        private bool AddPhysicsShape(MyStringId subtypeId, MyModel model, ref MatrixD worldMatrix, Vector3I sectorId, HkStaticCompoundShape sectorRootShape,
                                     Dictionary <MyStringId, HkShape> subtypeIdToShape, out int physicsShapeInstanceId)
        {
            physicsShapeInstanceId = 0;

            HkShape physicsShape;

            if (!subtypeIdToShape.TryGetValue(subtypeId, out physicsShape))
            {
                HkShape[] shapes = model.HavokCollisionShapes;
                if (shapes == null || shapes.Length == 0)
                {
                    return(false);
                }

                Debug.Assert(shapes.Length == 1);

                //List<HkShape> listShapes = new List<HkShape>();
                //for (int i = 0; i < shapes.Length; i++)
                //{
                //    listShapes.Add(shapes[i]);
                //    HkShape.SetUserData(shapes[i], shapes[i].UserData | (int)HkShapeUserDataFlags.EnvironmentItem);
                //}

                //physicsShape = new HkListShape(listShapes.GetInternalArray(), listShapes.Count, HkReferencePolicy.None);
                //HkShape.SetUserData(physicsShape, physicsShape.UserData | (int)HkShapeUserDataFlags.EnvironmentItem);
                physicsShape = shapes[0];
                physicsShape.AddReference();
                subtypeIdToShape[subtypeId] = physicsShape;
            }

            physicsShapeInstanceId = sectorRootShape.AddInstance(physicsShape, worldMatrix);
            Debug.Assert(physicsShapeInstanceId >= 0 && physicsShapeInstanceId < int.MaxValue, "Shape key space overflow");
            return(true);
        }
Example #38
0
 private string NameOf(Vector3I pos)
 {
     return($"region{pos.X:+0;-#}{pos.Y:+0;-#}{pos.Z:+0;-#}.vgz");
 }
Example #39
0
            public void SetTile(TileData tile)
            {
                var offset = new Vector3I(tile._indexX, tile._indexY, tile._indexZ) - Region * RegionSize;

                tiles[(offset.Z * RegionSize + offset.Y) * RegionSize + offset.X] = tile;
            }
Example #40
0
        internal MyClipmapHandler(uint id, MyClipmapScaleEnum scaleGroup, MatrixD worldMatrix, Vector3I sizeLod0, Vector3D massiveCenter, float massiveRadius, bool spherize, RenderFlags additionalFlags, VRage.Voxels.MyClipmap.PruningFunc prunningFunc)
        {
            m_clipmapBase   = new MyClipmap(id, scaleGroup, worldMatrix, sizeLod0, this, massiveCenter, massiveRadius, prunningFunc);
            m_massiveCenter = massiveCenter;
            m_renderFlags   = additionalFlags;
            m_mergeHandler  = null;

            if (spherize)
            {
                m_massiveRadius = massiveRadius;
            }

            if (MyLodMeshMergeHandler.ShouldAllocate(m_mergeHandler))
            {
                m_mergeHandler = AllocateMergeHandler();
            }

            MyClipmap.AddToUpdate(MyRender11.Environment.CameraPosition, Base);
        }
Example #41
0
 public MyVoxelFile(MyMwcVoxelFilesEnum voxelFileEnum, Vector3I sizeInVoxels, string voxelName)
 {
     VoxelFileEnum = voxelFileEnum;
     SizeInVoxels  = sizeInVoxels;
     VoxelName     = voxelName;
 }
Example #42
0
 internal ForesterBlockPlacingEventArgs(Vector3I coordinate, Block block)
 {
     Coordinate = coordinate;
     Block      = block;
 }
Example #43
0
        public MyObjectBuilder_EntityBase BuildEntity()
        {
            var asteroidCenter = new VRageMath.Vector3D();
            var asteroidSize   = new Vector3I();

            string originalFile = null;

            if (IsStockVoxel)
            {
                var stockfile = StockVoxel.SourceFilename;

                if (StockMaterial == null || StockMaterial.Value == null)
                {
                    SourceFile   = stockfile;
                    originalFile = SourceFile;
                    var asteroid = new MyVoxelMap();
                    asteroid.Load(stockfile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), false);
                    asteroidCenter = asteroid.BoundingContent.Center;
                    asteroidSize   = asteroid.BoundingContent.SizeInt() + 1; // Content size
                }
                else
                {
                    var asteroid = new MyVoxelMap();
                    asteroid.Load(stockfile, StockMaterial.Value);
                    asteroid.ForceBaseMaterial(SpaceEngineersCore.Resources.GetDefaultMaterialName(), StockMaterial.Value);
                    SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                    asteroid.Save(SourceFile);

                    originalFile   = StockVoxel.SourceFilename;
                    asteroidCenter = asteroid.BoundingContent.Center;
                    asteroidSize   = asteroid.BoundingContent.SizeInt() + 1; // Content size
                }
            }
            else if (IsFileVoxel)
            {
                originalFile = SourceFile;

                var asteroid = new MyVoxelMap();
                asteroid.Load(SourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), false);
                asteroidCenter = asteroid.BoundingContent.Center;
                asteroidSize   = asteroid.BoundingContent.SizeInt() + 1; // Content size

                if (StockMaterial != null && StockMaterial.Value != null)
                {
                    asteroid.ForceBaseMaterial(SpaceEngineersCore.Resources.GetDefaultMaterialName(), StockMaterial.Value);
                    SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                    asteroid.Save(SourceFile);
                }
            }
            else if (IsSphere)
            {
                string material;
                if (StockMaterial != null && StockMaterial.Value != null)
                {
                    material = StockMaterial.Value;
                }
                else
                {
                    material = SpaceEngineersCore.Resources.GetDefaultMaterialName();
                }

                originalFile = string.Format("sphere_{0}_{1}_{2}{3}", material.ToLowerInvariant(), SphereRadius, SphereShellRadius, MyVoxelMap.V2FileExtension);

                var asteroid = MyVoxelBuilder.BuildAsteroidSphere(SphereRadius > 32, SphereRadius, material, material, SphereShellRadius != 0, SphereShellRadius);
                // TODO: progress bar.
                asteroidCenter = asteroid.BoundingContent.Center;
                asteroidSize   = asteroid.BoundingContent.SizeInt() + 1; // Content size
                SourceFile     = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                asteroid.Save(SourceFile);
            }

            // automatically number all files, and check for duplicate filenames.
            Filename = MainViewModel.CreateUniqueVoxelStorageName(originalFile);

            // Figure out where the Character is facing, and plant the new constrcut right in front.
            // Calculate the hypotenuse, as it will be the safest distance to place in front.
            double distance = Math.Sqrt(Math.Pow(asteroidSize.X, 2) + Math.Pow(asteroidSize.Y, 2) + Math.Pow(asteroidSize.Z, 2)) / 2;

            var vector = new BindableVector3DModel(_dataModel.CharacterPosition.Forward).Vector3D;

            vector.Normalize();
            vector   = System.Windows.Media.Media3D.Vector3D.Multiply(vector, distance);
            Position = new BindablePoint3DModel(Point3D.Add(new BindablePoint3DModel(_dataModel.CharacterPosition.Position).Point3D, vector));
            //Forward = new BindableVector3DModel(_dataModel.CharacterPosition.Forward);
            //Up = new BindableVector3DModel(_dataModel.CharacterPosition.Up);
            Forward = new BindableVector3DModel(Vector3.Forward);  // Asteroids currently don't have any orientation.
            Up      = new BindableVector3DModel(Vector3.Up);

            var entity = new MyObjectBuilder_VoxelMap
            {
                EntityId               = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID),
                PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                StorageName            = Path.GetFileNameWithoutExtension(Filename),
                PositionAndOrientation = new MyPositionAndOrientation
                {
                    Position = Position.ToVector3D() - asteroidCenter,
                    Forward  = Forward.ToVector3(),
                    Up       = Up.ToVector3()
                }
            };

            return(entity);
        }
Example #44
0
        private RegionData LoadRegionFile(string name, Vector3I region)
        {
            RegionData data = null;

            lock (dataCache)
            {
                foreach (var rgn in dataCache)
                {
                    if (rgn.Region == region)
                    {
                        data = rgn;
                        break;
                    }
                }

                if (data != null)
                {
                    dataCache.Remove(data);
                    dataCache.Add(data);

                    while (dataCache.Count > 5)
                    {
                        dataCache.RemoveAt(0);
                    }

                    return(data);
                }

                data = new RegionData()
                {
                    Region = region
                };
                dataCache.Add(data);

                while (dataCache.Count > 5)
                {
                    dataCache.RemoveAt(0);
                }
            }

            lock (data)
            {
                var formatter = new BinaryFormatter();
                var path      = Path.Combine(SaveFolder.FullName, name);
                if (File.Exists(path))
                {
                    byte[] mdata;
                    using (var gzs = new GZipStream(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), CompressionMode.Decompress))
                    {
                        using (var mems = new MemoryStream())
                        {
                            gzs.CopyTo(mems);
                            mems.Close();
                            mdata = mems.ToArray();
                        }
                    }

                    using (var sw = new RiffFile(new MemoryStream(mdata)))
                    {
                        foreach (var chunk in sw.Chunks)
                        {
                            switch (chunk.ChunkId)
                            {
                            case "RMTA": // Region file meta
                            {
                                var version = chunk.ReadByte();
                                if (version != 1)
                                {
                                    throw new NotImplementedException();
                                }
                            }
                            break;

                            case "LIST":
                            {
                                var list = chunk.ToList();
                                switch (list.ListId)
                                {
                                case "TILS":
                                    foreach (var chunk2 in list.Chunks)
                                    {
                                        switch (chunk2.ChunkId)
                                        {
                                        case "LIST":
                                        {
                                            var list2 = chunk2.ToList();
                                            switch (list2.ListId)
                                            {
                                            case "TILE":
                                            {
                                                var tileData = new RegionData.TileData();
                                                foreach (var chunk3 in list2.Chunks)
                                                {
                                                    switch (chunk3.ChunkId)
                                                    {
                                                    case "TMTA":
                                                        tileData._indexX          = chunk3.ReadInt32();
                                                        tileData._indexY          = chunk3.ReadInt32();
                                                        tileData._indexZ          = chunk3.ReadInt32();
                                                        tileData._generationState = chunk3.ReadInt32();
                                                        data.SetTile(tileData);
                                                        break;

                                                    case "HMAP":
                                                    {
                                                        var a = (int[])formatter.Deserialize(chunk);
                                                        Array.Copy(a, tileData._heightmap, a.Length);
                                                    }
                                                    break;

                                                    case "BLKS":
                                                    {
                                                        var a = (ushort[])formatter.Deserialize(chunk);
                                                        Array.Copy(a, tileData._gridBlock, a.Length);
                                                    }
                                                    break;

                                                    case "LIST":
                                                    {
                                                        var list3 = chunk3.ToList();
                                                        switch (list3.ListId)
                                                        {
                                                        case "TXTA":
                                                            break;

                                                        case "ENTS":
                                                            break;
                                                        }
                                                    }
                                                    break;
                                                    }
                                                }
                                            }
                                            break;
                                            }
                                        }
                                        break;
                                        }
                                    }
                                    break;
                                }
                            }
                            break;
                            }

                            //            // Block Extra Data
                            //            using (var extraData = tileList.CreateList("TXTA"))
                            //            {
                            //                foreach (var byteArray in tile._gridExtra)
                            //                {
                            //                    using (var blockExtra = extraData.CreateChunk("BXTA"))
                            //                    {
                            //                        formatter.Serialize(blockExtra, byteArray);
                            //                    }
                            //                }
                            //            }

                            //            // Entities
                            //            using (var entityData = tileList.CreateList("ENTS"))
                            //            {
                            //                foreach (var byteArray in tile._gridEntities)
                            //                {
                            //                    using (var blockExtra = entityData.CreateChunk("ENTY"))
                            //                    {
                            //                        formatter.Serialize(blockExtra, byteArray);
                            //                    }
                            //                }
                            //            }
                        }
                    }
                }

                return(data);
            }
        }
        // For a 1024 cubed asteroid, it takes approximately 6.5Gb of system memory.

        public static MyVoxelMap ReadModelAsteroidVolmetic(Model3DGroup model, IList <MyMeshModel> mappedMesh, ScaleTransform3D scale, Transform3D rotateTransform, TraceType traceType, TraceCount traceCount, TraceDirection traceDirection,
                                                           Action <double, double> resetProgress, Action incrementProgress, Func <bool> checkCancel, Action complete)
        {
            var traceDirectionCount = 0;
            var materials           = new List <byte>();
            var faceMaterials       = new List <byte>();

            foreach (var mesh in mappedMesh)
            {
                if (string.IsNullOrEmpty(mesh.Material))
                {
                    materials.Add(0xff); // represent empty materials.
                }
                else
                {
                    materials.Add(SpaceEngineersCore.Resources.GetMaterialIndex(mesh.Material));
                }

                if (string.IsNullOrEmpty(mesh.FaceMaterial))
                {
                    faceMaterials.Add(0xff); // represent empty materials.
                }
                else
                {
                    faceMaterials.Add(SpaceEngineersCore.Resources.GetMaterialIndex(mesh.FaceMaterial));
                }
            }

            // How far to check in from the proposed Volumetric edge.
            // This number is just made up, but small enough that it still represents the corner edge of the Volumetric space.
            // But still large enough that it isn't the exact corner.
            const double offset = 0.0000045f;

            if (scale.ScaleX > 0 && scale.ScaleY > 0 && scale.ScaleZ > 0 && scale.ScaleX != 1.0f && scale.ScaleY != 1.0f && scale.ScaleZ != 1.0f)
            {
                model.TransformScale(scale.ScaleX, scale.ScaleY, scale.ScaleZ);
            }

            // Attempt to offset the model, so it's only caulated from zero (0) and up, instead of using zero (0) as origin.
            //model.Transform = new TranslateTransform3D(-model.Bounds.X, -model.Bounds.Y, -model.Bounds.Z);

            var      tbounds = model.Bounds;
            Matrix3D?rotate  = null;

            if (rotateTransform != null)
            {
                rotate  = rotateTransform.Value;
                tbounds = rotateTransform.TransformBounds(tbounds);
            }

            //model.Transform = new TranslateTransform3D(-tbounds.X, -tbounds.Y, -tbounds.Z);

            // Add 2 to either side, to allow for material padding to expose internal materials.
            var xMin = (int)Math.Floor(tbounds.X) - 2;
            var yMin = (int)Math.Floor(tbounds.Y) - 2;
            var zMin = (int)Math.Floor(tbounds.Z) - 2;

            var xMax = (int)Math.Ceiling(tbounds.X + tbounds.SizeX) + 2;
            var yMax = (int)Math.Ceiling(tbounds.Y + tbounds.SizeY) + 2;
            var zMax = (int)Math.Ceiling(tbounds.Z + tbounds.SizeZ) + 2;

            var xCount = (xMax - xMin).RoundUpToNearest(64);
            var yCount = (yMax - yMin).RoundUpToNearest(64);
            var zCount = (zMax - zMin).RoundUpToNearest(64);

            Debug.WriteLine("Approximate Size: {0}x{1}x{2}", Math.Ceiling(tbounds.X + tbounds.SizeX) - Math.Floor(tbounds.X), Math.Ceiling(tbounds.Y + tbounds.SizeY) - Math.Floor(tbounds.Y), Math.Ceiling(tbounds.Z + tbounds.SizeZ) - Math.Floor(tbounds.Z));
            Debug.WriteLine("Bounds Size: {0}x{1}x{2}", xCount, yCount, zCount);

            var finalCubic = ArrayHelper.Create <byte>(xCount, yCount, zCount);
            var finalMater = ArrayHelper.Create <byte>(xCount, yCount, zCount);

            if (resetProgress != null)
            {
                long triangles = (from GeometryModel3D gm in model.Children select gm.Geometry as MeshGeometry3D).Aggregate <MeshGeometry3D, long>(0, (current, g) => current + (g.TriangleIndices.Count / 3));
                long rays      = 0;

                if ((traceDirection & TraceDirection.X) == TraceDirection.X)
                {
                    rays += ((yMax - yMin) * (zMax - zMin));
                }
                if ((traceDirection & TraceDirection.Y) == TraceDirection.Y)
                {
                    rays += ((xMax - xMin) * (zMax - zMin));
                }
                if ((traceDirection & TraceDirection.Z) == TraceDirection.Z)
                {
                    rays += ((xMax - xMin) * (yMax - yMin));
                }

                resetProgress.Invoke(0, rays * triangles);
            }

            if (checkCancel != null && checkCancel.Invoke())
            {
                if (complete != null)
                {
                    complete.Invoke();
                }
                return(null);
            }

            #region basic ray trace of every individual triangle.

            // Start from the last mesh, which represents the bottom of the UI stack, and overlay each other mesh on top of it.
            for (var modelIdx = mappedMesh.Count - 1; modelIdx >= 0; modelIdx--)
            {
                Debug.WriteLine("Model {0}", modelIdx);

                var modelCubic = new byte[xCount][][];
                var modelMater = new byte[xCount][][];

                for (var x = 0; x < xCount; x++)
                {
                    modelCubic[x] = new byte[yCount][];
                    modelMater[x] = new byte[yCount][];
                    for (var y = 0; y < yCount; y++)
                    {
                        modelCubic[x][y] = new byte[zCount];
                        modelMater[x][y] = new byte[zCount];
                    }
                }

                var meshes        = mappedMesh[modelIdx];
                var threadCounter = 0;

                var geometries = new GeometeryDetail[meshes.Geometery.Length];
                for (var i = 0; i < meshes.Geometery.Length; i++)
                {
                    geometries[i] = new GeometeryDetail(meshes.Geometery[i]);
                }

                var startOffset              = 0.5f;
                var endOffset                = 0.5f;
                var volumeOffset             = 0.5f;
                Func <double, int> roundFunc = null;
                if (traceType == TraceType.Odd)
                {
                    startOffset  = 0.5f;
                    endOffset    = 0.5f;
                    volumeOffset = 0.5f;
                    roundFunc    = delegate(double d) { return((int)Math.Round(d, 0)); };
                }
                else if (traceType == TraceType.Even)
                {
                    startOffset  = 0.0f;
                    endOffset    = 1.0f;
                    volumeOffset = 1.0f;
                    roundFunc    = delegate(double d) { return((int)Math.Floor(d)); };
                }

                #region X ray trace

                if ((traceDirection & TraceDirection.X) == TraceDirection.X)
                {
                    Debug.WriteLine("X Rays");
                    traceDirectionCount++;
                    threadCounter = (yMax - yMin) * (zMax - zMin);

                    for (var y = yMin; y < yMax; y++)
                    {
                        for (var z = zMin; z < zMax; z++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                if (complete != null)
                                {
                                    complete.Invoke();
                                }
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset) },
                                    new [] { new Point3D(xMin, y - 0.5f + offset, z - 0.5f + offset), new Point3D(xMax, y - 0.5f + offset, z - 0.5f + offset) },
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z - 0.5f + offset), new Point3D(xMax, y + 0.5f - offset, z - 0.5f + offset) },
                                    new [] { new Point3D(xMin, y - 0.5f + offset, z + 0.5f - offset), new Point3D(xMax, y - 0.5f + offset, z + 0.5f - offset) },
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z + 0.5f - offset), new Point3D(xMax, y + 0.5f - offset, z + 0.5f - offset) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(xMin, y + 0.5f - offset, z + 0.5f - offset), new Point3D(xMax, y + 0.5f - offset, z + 0.5f - offset) },
                                    new [] { new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset) },
                                    new [] { new Point3D(xMin, y + 1.0f - offset, z + offset), new Point3D(xMax, y + 1.0f - offset, z + offset) },
                                    new [] { new Point3D(xMin, y + offset, z + 1.0f - offset), new Point3D(xMax, y + offset, z + 1.0f - offset) },
                                    new [] { new Point3D(xMin, y + 1.0f - offset, z + 1.0f - offset), new Point3D(xMax, y + 1.0f - offset, z + 1.0f - offset) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.Y < ray[0].Y && p2.Y < ray[0].Y && p3.Y < ray[0].Y) ||
                                                (p1.Y > ray[0].Y && p2.Y > ray[0].Y && p3.Y > ray[0].Y) ||
                                                (p1.Z < ray[0].Z && p2.Z < ray[0].Z && p3.Z < ray[0].Z) ||
                                                (p1.Z > ray[0].Z && p2.Z > ray[0].Z && p3.Z > ray[0].Z))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.X).ToArray();
                                    var startCoord = roundFunc(order[0].Point.X);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.X);
                                    var surfaces   = 0;

                                    for (var x = startCoord; x <= endCoord; x++)
                                    {
                                        var points = order.Where(p => p.Point.X > x - startOffset && p.Point.X < x + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(x + volumeOffset - point.Point.X) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(x + volumeOffset - point.Point.X) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        // TODO: retest detailed model export.
                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[x - xMin][bgw.Y - yMin][bgw.Z - zMin] = volume;
                                        modelMater[x - xMin][bgw.Y - yMin][bgw.Z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (xMin < startCoord - i && modelCubic[startCoord - i - xMin][bgw.Y - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[startCoord - i - xMin][bgw.Y - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < xMax && modelCubic[endCoord + i - xMin][bgw.Y - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[endCoord + i - xMin][bgw.Y - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, 0, y, z));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                #region Y rays trace

                if ((traceDirection & TraceDirection.Y) == TraceDirection.Y)
                {
                    Debug.WriteLine("Y Rays");
                    traceDirectionCount++;
                    threadCounter = (xMax - xMin) * (zMax - zMin);

                    for (var x = xMin; x < xMax; x++)
                    {
                        for (var z = zMin; z < zMax; z++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                if (complete != null)
                                {
                                    complete.Invoke();
                                }
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset) },
                                    new [] { new Point3D(x - 0.5f + offset, yMin, z - 0.5f + offset), new Point3D(x - 0.5f + offset, yMax, z - 0.5f + offset) },
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z - 0.5f + offset), new Point3D(x + 0.5f - offset, yMax, z - 0.5f + offset) },
                                    new [] { new Point3D(x - 0.5f + offset, yMin, z + 0.5f - offset), new Point3D(x - 0.5f + offset, yMax, z + 0.5f - offset) },
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z + 0.5f - offset), new Point3D(x + 0.5f - offset, yMax, z + 0.5f - offset) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + 0.5f - offset, yMin, z + 0.5f - offset), new Point3D(x + 0.5f - offset, yMax, z + 0.5f - offset) },
                                    new [] { new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset) },
                                    new [] { new Point3D(x + 1.0f - offset, yMin, z + offset), new Point3D(x + 1.0f - offset, yMax, z + offset) },
                                    new [] { new Point3D(x + offset, yMin, z + 1.0f - offset), new Point3D(x + offset, yMax, z + 1.0f - offset) },
                                    new [] { new Point3D(x + 1.0f - offset, yMin, z + 1.0f - offset), new Point3D(x + 1.0f - offset, yMax, z + 1.0f - offset) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.X < ray[0].X && p2.X < ray[0].X && p3.X < ray[0].X) ||
                                                (p1.X > ray[0].X && p2.X > ray[0].X && p3.X > ray[0].X) ||
                                                (p1.Z < ray[0].Z && p2.Z < ray[0].Z && p3.Z < ray[0].Z) ||
                                                (p1.Z > ray[0].Z && p2.Z > ray[0].Z && p3.Z > ray[0].Z))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.Y).ToArray();
                                    var startCoord = roundFunc(order[0].Point.Y);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.Y);
                                    var surfaces   = 0;

                                    for (var y = startCoord; y <= endCoord; y++)
                                    {
                                        var points = order.Where(p => p.Point.Y > y - startOffset && p.Point.Y < y + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(y + volumeOffset - point.Point.Y) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(y + volumeOffset - point.Point.Y) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        if (traceDirectionCount > 1)
                                        {
                                            var prevolumme = modelCubic[bgw.X - xMin][y - yMin][bgw.Z - zMin];
                                            if (prevolumme != 0)
                                            {
                                                // average with the pre-existing X volume.
                                                volume = (byte)Math.Round(((float)prevolumme + (float)volume) / (float)traceDirectionCount, 0);
                                            }
                                        }

                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[bgw.X - xMin][y - yMin][bgw.Z - zMin] = volume;
                                        modelMater[bgw.X - xMin][y - yMin][bgw.Z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (yMin < startCoord - i && modelCubic[bgw.X - xMin][startCoord - i - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][startCoord - i - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < yMax && modelCubic[bgw.X - xMin][endCoord + i - yMin][bgw.Z - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][endCoord + i - yMin][bgw.Z - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, x, 0, z));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                #region Z ray trace

                if ((traceDirection & TraceDirection.Z) == TraceDirection.Z)
                {
                    Debug.WriteLine("Z Rays");
                    traceDirectionCount++;
                    threadCounter = (xMax - xMin) * (yMax - yMin);

                    for (var x = xMin; x < xMax; x++)
                    {
                        for (var y = yMin; y < yMax; y++)
                        {
                            if (checkCancel != null && checkCancel.Invoke())
                            {
                                if (complete != null)
                                {
                                    complete.Invoke();
                                }
                                return(null);
                            }

                            List <Point3D[]> testRays = null;
                            if (traceType == TraceType.Odd)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax) },
                                    new [] { new Point3D(x - 0.5f + offset, y - 0.5f + offset, zMin), new Point3D(x - 0.5f + offset, y - 0.5f + offset, zMax) },
                                    new [] { new Point3D(x + 0.5f - offset, y - 0.5f + offset, zMin), new Point3D(x + 0.5f - offset, y - 0.5f + offset, zMax) },
                                    new [] { new Point3D(x - 0.5f + offset, y + 0.5f - offset, zMin), new Point3D(x - 0.5f + offset, y + 0.5f - offset, zMax) },
                                    new [] { new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMin), new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMax) }
                                }
                            }
                            ;
                            else if (traceType == TraceType.Even)
                            {
                                testRays = new List <Point3D[]>
                                {
                                    new [] { new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMin), new Point3D(x + 0.5f - offset, y + 0.5f - offset, zMax) },
                                    new [] { new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax) },
                                    new [] { new Point3D(x + 1.0f - offset, y + offset, zMin), new Point3D(x + 1.0f - offset, y + offset, zMax) },
                                    new [] { new Point3D(x + offset, y + 1.0f - offset, zMin), new Point3D(x + offset, y + 1.0f - offset, zMax) },
                                    new [] { new Point3D(x + 1.0f - offset, y + 1.0f - offset, zMin), new Point3D(x + 1.0f - offset, y + 1.0f - offset, zMax) }
                                }
                            }
                            ;

                            var task = new Task(obj =>
                            {
                                var bgw     = (RayTracerTaskWorker)obj;
                                var tracers = new List <Trace>();

                                foreach (var geometery in geometries)
                                {
                                    for (var t = 0; t < geometery.Triangles.Length; t += 3)
                                    {
                                        if (checkCancel != null && checkCancel.Invoke())
                                        {
                                            return;
                                        }

                                        if (incrementProgress != null)
                                        {
                                            lock (Locker)
                                            {
                                                incrementProgress.Invoke();
                                            }
                                        }

                                        var p1 = geometery.Positions[geometery.Triangles[t]];
                                        var p2 = geometery.Positions[geometery.Triangles[t + 1]];
                                        var p3 = geometery.Positions[geometery.Triangles[t + 2]];

                                        if (rotate.HasValue)
                                        {
                                            p1 = rotate.Value.Transform(p1);
                                            p2 = rotate.Value.Transform(p2);
                                            p3 = rotate.Value.Transform(p3);
                                        }

                                        foreach (var ray in testRays)
                                        {
                                            if ((p1.X < ray[0].X && p2.X < ray[0].X && p3.X < ray[0].X) ||
                                                (p1.X > ray[0].X && p2.X > ray[0].X && p3.X > ray[0].X) ||
                                                (p1.Y < ray[0].Y && p2.Y < ray[0].Y && p3.Y < ray[0].Y) ||
                                                (p1.Y > ray[0].Y && p2.Y > ray[0].Y && p3.Y > ray[0].Y))
                                            {
                                                continue;
                                            }

                                            Point3D intersect;
                                            int normal;
                                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, ray[0], ray[1], out intersect, out normal))
                                            {
                                                tracers.Add(new Trace(intersect, normal));
                                            }
                                        }
                                    }
                                }

                                if (tracers.Count > 1)
                                {
                                    var order      = tracers.GroupBy(t => new { t.Point, t.Face }).Select(g => g.First()).OrderBy(k => k.Point.Z).ToArray();
                                    var startCoord = roundFunc(order[0].Point.Z);
                                    var endCoord   = roundFunc(order[order.Length - 1].Point.Z);
                                    var surfaces   = 0;

                                    for (var z = startCoord; z <= endCoord; z++)
                                    {
                                        var points = order.Where(p => p.Point.Z > z - startOffset && p.Point.Z < z + endOffset).ToArray();
                                        var volume = (byte)(0xff / testRays.Count * surfaces);

                                        foreach (var point in points)
                                        {
                                            if (point.Face == MeshFace.Farside)
                                            {
                                                volume += (byte)(Math.Round(Math.Abs(z + volumeOffset - point.Point.Z) * 255 / testRays.Count, 0));
                                                surfaces++;
                                            }
                                            else if (point.Face == MeshFace.Nearside)
                                            {
                                                volume -= (byte)(Math.Round(Math.Abs(z + volumeOffset - point.Point.Z) * 255 / testRays.Count, 0));
                                                surfaces--;
                                            }
                                        }

                                        if (traceDirectionCount > 1)
                                        {
                                            var prevolumme = modelCubic[bgw.X - xMin][bgw.Y - yMin][z - zMin];
                                            if (prevolumme != 0)
                                            {
                                                // average with the pre-existing X and Y volumes.
                                                volume = (byte)Math.Round((((float)prevolumme * (traceDirectionCount - 1)) + (float)volume) / (float)traceDirectionCount, 0);
                                            }
                                        }

                                        //volume = volume.RoundUpToNearest(8);

                                        modelCubic[bgw.X - xMin][bgw.Y - yMin][z - zMin] = volume;
                                        modelMater[bgw.X - xMin][bgw.Y - yMin][z - zMin] = materials[bgw.ModelIdx];
                                    }

                                    if (faceMaterials[bgw.ModelIdx] != 0xff)
                                    {
                                        for (var i = 1; i < 6; i++)
                                        {
                                            if (zMin < startCoord - i && modelCubic[bgw.X - xMin][bgw.Y - yMin][startCoord - i - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][bgw.Y - yMin][startCoord - i - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                            if (endCoord + i < zMax && modelCubic[bgw.X - xMin][bgw.Y - yMin][endCoord + i - zMin] == 0)
                                            {
                                                modelMater[bgw.X - xMin][bgw.Y - yMin][endCoord + i - zMin] = faceMaterials[bgw.ModelIdx];
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    threadCounter--;
                                }
                            }, new RayTracerTaskWorker(modelIdx, x, y, 0));

                            task.Start();
                        }
                    }

                    // Wait for Multithread parts to finish.
                    while (threadCounter > 0)
                    {
                        System.Windows.Forms.Application.DoEvents();
                        if (checkCancel != null && checkCancel.Invoke())
                        {
                            break;
                        }
                    }

                    GC.Collect();
                }

                #endregion

                if (checkCancel != null && checkCancel.Invoke())
                {
                    if (complete != null)
                    {
                        complete.Invoke();
                    }
                    return(null);
                }

                #region merge individual model results into final

                for (var x = 0; x < xCount; x++)
                {
                    for (var y = 0; y < yCount; y++)
                    {
                        for (var z = 0; z < zCount; z++)
                        {
                            if (modelMater[x][y][z] == 0xff && modelCubic[x][y][z] != 0)
                            {
                                finalCubic[x][y][z] = (byte)Math.Max(finalCubic[x][y][z] - modelCubic[x][y][z], 0);
                            }
                            else if (modelCubic[x][y][z] != 0)
                            {
                                finalCubic[x][y][z] = Math.Max(finalCubic[x][y][z], modelCubic[x][y][z]);
                                finalMater[x][y][z] = modelMater[x][y][z];
                            }
                            else if (finalCubic[x][y][z] == 0 && finalMater[x][y][z] == 0 && modelMater[x][y][z] != 0xff)
                            {
                                finalMater[x][y][z] = modelMater[x][y][z];
                            }
                        }
                    }
                }

                #endregion
            } // end models

            #endregion

            if (checkCancel != null && checkCancel.Invoke())
            {
                if (complete != null)
                {
                    complete.Invoke();
                }
                return(null);
            }

            var size = new Vector3I(xCount, yCount, zCount);
            // TODO: at the moment the Mesh list is not complete, so the faceMaterial setting is kind of vague.
            var defaultMaterial = mappedMesh[0].Material;     // Use the FaceMaterial from the first Mesh in the object list.
            var faceMaterial    = mappedMesh[0].FaceMaterial; // Use the FaceMaterial from the first Mesh in the object list.

            var action = (Action <MyVoxelBuilderArgs>) delegate(MyVoxelBuilderArgs e)
            {
                e.Volume   = finalCubic[e.CoordinatePoint.X][e.CoordinatePoint.Y][e.CoordinatePoint.Z];
                e.Material = SpaceEngineersCore.Resources.GetMaterialName(finalMater[e.CoordinatePoint.X][e.CoordinatePoint.Y][e.CoordinatePoint.Z]);
            };

            var voxelMap = MyVoxelBuilder.BuildAsteroid(true, size, defaultMaterial, faceMaterial, action);

            if (complete != null)
            {
                complete.Invoke();
            }

            return(voxelMap);
        }
Example #46
0
 static void Add(MyMwcVoxelFilesEnum voxelFileEnum, Vector3I sizeInVoxels, string filename)
 {
     DefaultVoxelFiles[(int)voxelFileEnum] = new MyVoxelFile(voxelFileEnum, sizeInVoxels, filename);
 }
 bool CanPlace(Vector3I coords)
 {
     return((Map.GetBlock(coords) == SourceBlock) &&
            Player.CanPlace(Map, coords, ReplacementBlock, Context) == CanPlaceResult.Allowed);
 }
Example #48
0
        public void TestVoxelNavmeshTriangle(ref Vector3D a, ref Vector3D b, ref Vector3D c, List <MyCubeGrid> gridsToTest, List <MyGridPathfinding.CubeId> linkCandidatesOutput, out bool intersecting)
        {
            Vector3D point = ((a + b) + c) / 3.0;

            if (this.m_obstacles.IsInObstacle(point))
            {
                intersecting = true;
                return;
            }
            Vector3D zero = Vector3D.Zero;

            if (MyPerGameSettings.NavmeshPresumesDownwardGravity)
            {
                zero = Vector3.Down * 2f;
            }
            m_tmpLinkCandidates.Clear();
            intersecting = false;
            using (List <MyCubeGrid> .Enumerator enumerator = gridsToTest.GetEnumerator())
            {
                goto TR_0016;
TR_0008:
                if (intersecting)
                {
                    goto TR_0006;
                }
TR_0016:
                while (true)
                {
                    if (enumerator.MoveNext())
                    {
                        Vector3D   vectord2;
                        Vector3D   vectord3;
                        Vector3D   vectord4;
                        Vector3D   vectord5;
                        MyCubeGrid current = enumerator.Current;
                        MatrixD    worldMatrixNormalizedInv = current.PositionComp.WorldMatrixNormalizedInv;
                        Vector3D.Transform(ref a, ref worldMatrixNormalizedInv, out vectord2);
                        Vector3D.Transform(ref b, ref worldMatrixNormalizedInv, out vectord3);
                        Vector3D.Transform(ref c, ref worldMatrixNormalizedInv, out vectord4);
                        Vector3D.TransformNormal(ref zero, ref worldMatrixNormalizedInv, out vectord5);
                        BoundingBoxD xd = new BoundingBoxD(Vector3D.MaxValue, Vector3D.MinValue);
                        xd.Include(ref vectord2, ref vectord3, ref vectord4);
                        Vector3I vectori  = current.LocalToGridInteger((Vector3)xd.Min);
                        Vector3I vectori2 = current.LocalToGridInteger((Vector3)xd.Max);
                        Vector3I start    = vectori - Vector3I.One;
                        Vector3I end      = (Vector3I)(vectori2 + Vector3I.One);
                        Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref start, ref end);
                        while (iterator.IsValid())
                        {
                            if (current.GetCubeBlock(start) != null)
                            {
                                Vector3      min     = (Vector3)((start - Vector3.One) * current.GridSize);
                                Vector3      max     = (start + Vector3.One) * current.GridSize;
                                Vector3      vector3 = (Vector3)((start - Vector3.Half) * current.GridSize);
                                Vector3      vector4 = (start + Vector3.Half) * current.GridSize;
                                BoundingBoxD xd3     = new BoundingBoxD(min, max);
                                BoundingBoxD xd4     = new BoundingBoxD(vector3, vector4);
                                xd3.Include(min + vectord5);
                                xd3.Include(max + vectord5);
                                xd4.Include(vector3 + vectord5);
                                xd4.Include(vector4 + vectord5);
                                if (xd3.IntersectsTriangle(ref vectord2, ref vectord3, ref vectord4))
                                {
                                    if (xd4.IntersectsTriangle(ref vectord2, ref vectord3, ref vectord4))
                                    {
                                        intersecting = true;
                                        break;
                                    }
                                    int num3 = Math.Min(Math.Abs((int)(vectori.Z - start.Z)), Math.Abs((int)(vectori2.Z - start.Z)));
                                    if (((Math.Min(Math.Abs((int)(vectori.X - start.X)), Math.Abs((int)(vectori2.X - start.X))) + Math.Min(Math.Abs((int)(vectori.Y - start.Y)), Math.Abs((int)(vectori2.Y - start.Y)))) + num3) < 3)
                                    {
                                        MyGridPathfinding.CubeId item = new MyGridPathfinding.CubeId {
                                            Grid   = current,
                                            Coords = start
                                        };
                                        m_tmpLinkCandidates.Add(item);
                                    }
                                }
                            }
                            iterator.GetNext(out start);
                        }
                    }
                    else
                    {
                        goto TR_0006;
                    }
                    break;
                }
                goto TR_0008;
            }
TR_0006:
            if (!intersecting)
            {
                for (int i = 0; i < m_tmpLinkCandidates.Count; i++)
                {
                    linkCandidatesOutput.Add(m_tmpLinkCandidates[i]);
                }
            }
            m_tmpLinkCandidates.Clear();
        }
Example #49
0
        private static double[,] InterpolateResult(double[,] dataNoises,
                                                   Vector3I NoiseSampledSteps,
                                                   Vector3I StepsCount)
        {
            int nbrNoises = dataNoises.GetLength(1);

            //Create a new array with expended size
            double[,] result = new double[StepsCount.X * StepsCount.Y * StepsCount.Z, nbrNoises];

            int dataNoisesXSize = NoiseSampledSteps.X + 1;
            int dataNoisesYSize = NoiseSampledSteps.Y + 1;
            int dataNoisesZSize = NoiseSampledSteps.Z + 1;

            int XPointLerpedCount = StepsCount.X / NoiseSampledSteps.X;
            int ZPointLerpedCount = StepsCount.Z / NoiseSampledSteps.Z;
            int YPointLerpedCount = StepsCount.Y / NoiseSampledSteps.Y;

            //Loop against the generated noise values
            int noiseGeneratedResultIndex = 0;

            for (int noiseId = 0; noiseId < nbrNoises; noiseId++)
            {
                for (int SampledpointX = 0; SampledpointX < NoiseSampledSteps.X; SampledpointX++)
                {
                    for (int SampledpointZ = 0; SampledpointZ < NoiseSampledSteps.Z; SampledpointZ++)
                    {
                        for (int SampledpointY = 0; SampledpointY < NoiseSampledSteps.Y; SampledpointY++)
                        {
                            double NoiseX0Z0Y0 = dataNoises[((SampledpointX + 0) * dataNoisesZSize + (SampledpointZ + 0)) * dataNoisesYSize + (SampledpointY + 0), noiseId];
                            double NoiseX0Z1Y0 = dataNoises[((SampledpointX + 0) * dataNoisesZSize + (SampledpointZ + 1)) * dataNoisesYSize + (SampledpointY + 0), noiseId];
                            double NoiseX1Z0Y0 = dataNoises[((SampledpointX + 1) * dataNoisesZSize + (SampledpointZ + 0)) * dataNoisesYSize + (SampledpointY + 0), noiseId];
                            double NoiseX1Z1Y0 = dataNoises[((SampledpointX + 1) * dataNoisesZSize + (SampledpointZ + 1)) * dataNoisesYSize + (SampledpointY + 0), noiseId];

                            double DeltaX0Z0 = (dataNoises[((SampledpointX + 0) * dataNoisesZSize + (SampledpointZ + 0)) * dataNoisesYSize + (SampledpointY + 1), noiseId] - NoiseX0Z0Y0) / YPointLerpedCount; // 128 / 16 = 8 points need to be lerped 4 times !
                            double DeltaX0Z1 = (dataNoises[((SampledpointX + 0) * dataNoisesZSize + (SampledpointZ + 1)) * dataNoisesYSize + (SampledpointY + 1), noiseId] - NoiseX0Z1Y0) / YPointLerpedCount; // 128 / 16 = 8 points need to be lerped 4 times !
                            double DeltaX1Z0 = (dataNoises[((SampledpointX + 1) * dataNoisesZSize + (SampledpointZ + 0)) * dataNoisesYSize + (SampledpointY + 1), noiseId] - NoiseX1Z0Y0) / YPointLerpedCount; // 128 / 16 = 8 points need to be lerped 4 times !
                            double DeltaX1Z1 = (dataNoises[((SampledpointX + 1) * dataNoisesZSize + (SampledpointZ + 1)) * dataNoisesYSize + (SampledpointY + 1), noiseId] - NoiseX1Z1Y0) / YPointLerpedCount; // 128 / 16 = 8 points need to be lerped 4 times !

                            for (int Y = 0; Y < YPointLerpedCount; Y++)
                            {
                                double NoiseZ0 = NoiseX0Z0Y0;
                                double NoiseZ1 = NoiseX1Z0Y0;
                                double DeltaZ0 = (NoiseX0Z1Y0 - NoiseX0Z0Y0) / ZPointLerpedCount; // Chunk X length = 16 / 4 = 4 points needs to be lerped Twice!
                                double DeltaZ1 = (NoiseX1Z1Y0 - NoiseX1Z0Y0) / ZPointLerpedCount;
                                int    nY      = (SampledpointY * YPointLerpedCount) + Y;

                                for (int Z = 0; Z < ZPointLerpedCount; Z++)
                                {
                                    double NoiseFinalValue = NoiseZ0;
                                    double DeltaX          = (NoiseZ1 - NoiseZ0) / XPointLerpedCount; // Chunk Z length = 16 / 4 = 4 points needs to be lerped Once!
                                    int    nZ = (SampledpointZ * ZPointLerpedCount) + Z;
                                    for (int X = 0; X < XPointLerpedCount; X++)
                                    {
                                        int nX = (SampledpointX * XPointLerpedCount) + X;
                                        result[nX * StepsCount.Z * StepsCount.Y + nZ * StepsCount.Y + nY, noiseId] = NoiseFinalValue;

                                        noiseGeneratedResultIndex++;

                                        NoiseFinalValue += DeltaX;
                                    }
                                    NoiseZ0 += DeltaZ0;
                                    NoiseZ1 += DeltaZ1;
                                }
                                NoiseX0Z0Y0 += DeltaX0Z0;
                                NoiseX0Z1Y0 += DeltaX0Z1;
                                NoiseX1Z0Y0 += DeltaX1Z0;
                                NoiseX1Z1Y0 += DeltaX1Z1;
                            }
                        }
                    }
                }
            }

            return(result);
        }
        public override bool Prepare(Vector3I[] marks)
        {
            if (marks == null)
            {
                throw new ArgumentNullException("marks");
            }
            if (marks.Length < 1)
            {
                throw new ArgumentException("At least one mark needed.", "marks");
            }

            if (ReplacementBlock == Block.None)
            {
                if (Player.LastUsedBlockType == Block.None)
                {
                    Player.Message("Cannot deduce desired replacement block. Click a block or type out the block name.");
                    return(false);
                }
                else
                {
                    ReplacementBlock = Player.GetBind(Player.LastUsedBlockType);
                }
            }

            Marks       = marks;
            Origin      = marks[0];
            SourceBlock = Map.GetBlock(Origin);

            Vector3I playerCoords = Player.Position.ToBlockCoords();
            Vector3I lookVector   = (Origin - playerCoords);

            Axis = lookVector.LongestAxis;

            Vector3I maxDelta;

            maxFillExtent = Player.Info.Rank.FillLimit;
            if (maxFillExtent < 1 || maxFillExtent > 2048)
            {
                maxFillExtent = 2048;
            }

            switch (Axis)
            {
            case Axis.X:
                maxDelta        = new Vector3I(0, maxFillExtent, maxFillExtent);
                coordEnumerator = BlockEnumeratorX().GetEnumerator();
                break;

            case Axis.Y:
                maxDelta        = new Vector3I(maxFillExtent, 0, maxFillExtent);
                coordEnumerator = BlockEnumeratorY().GetEnumerator();
                break;

            default:     // Z
                maxDelta        = new Vector3I(maxFillExtent, maxFillExtent, 0);
                coordEnumerator = BlockEnumeratorZ().GetEnumerator();
                break;
            }
            if (SourceBlock == ReplacementBlock)
            {
                Bounds = new BoundingBox(Origin, Origin);
            }
            else
            {
                Bounds = new BoundingBox(Origin - maxDelta, Origin + maxDelta);
            }

            // Clip bounds to the map, used to limit fill extent
            Bounds = Bounds.GetIntersection(Map.Bounds);

            // Set everything up for filling
            Brush  = this;
            Coords = Origin;

            StartTime           = DateTime.UtcNow;
            Context             = BlockChangeContext.Drawn | BlockChangeContext.Filled;
            BlocksTotalEstimate = Bounds.Volume;

            return(true);
        }
Example #51
0
 private static void GetCellCorners(ref Vector3I minCorner, ref Vector3I maxCorner, ref Vector3I_RangeIterator it, out Vector3I cellMinCorner, out Vector3I cellMaxCorner)
 {
     cellMinCorner = new Vector3I(minCorner.X + it.Current.X * CELL_SIZE, minCorner.Y + it.Current.Y * CELL_SIZE, minCorner.Z + it.Current.Z * CELL_SIZE);
     cellMaxCorner = new Vector3I(Math.Min(maxCorner.X, cellMinCorner.X + CELL_SIZE), Math.Min(maxCorner.Y, cellMinCorner.Y + CELL_SIZE), Math.Min(maxCorner.Z, cellMinCorner.Z + CELL_SIZE));
 }
Example #52
0
        /// <summary>
        /// Will present the result of the noise inside a single Array[]
        /// The 3dimension are present inside this array in this order : X, Z and then Y
        /// It means to compute the array indice, use this formula : X * Zlength * Ylength + Z * Ylength + Y
        /// </summary>
        /// <param name="noiseFct">The Noise function</param>
        /// <param name="NoiseSampledSteps">The qt of steps that will be evaluated into by the noise fct, if qt below StepsCountX, the remaining Steps will be interpolated !! SampledSteps values MUST be a multiple of StepsCountn</param>
        /// <param name="FromX">Low X sampling Range</param>
        /// <param name="ToX">High X sampling Range</param>
        /// <param name="StepsCountX">Nbr of step sampled at equal distance from FromX to ToX</param>
        /// <param name="FromY">Low Y sampling Range</param>
        /// <param name="ToY">High Y sampling Range</param>
        /// <param name="StepsCountY">Nbr of step sampled at equal distance from FromY to ToY</param>
        /// <param name="FromZ">Low Z sampling Range</param>
        /// <param name="ToZ">High Z sampling Range</param>
        /// <param name="StepsCountZ">Nbr of step sampled at equal distance from FromZ to ToZ</param>
        /// <returns>Signle dimension array with the noise result</returns>
        public static double[,] NoiseSampling(Vector3I NoiseSampledSteps,
                                              double FromX, double ToX, int StepsCountX,
                                              double FromY, double ToY, int StepsCountY,
                                              double FromZ, double ToZ, int StepsCountZ,
                                              params INoise3[] noiseFcts)
        {
            bool needInterpolation = false;

            if (NoiseSampledSteps.X != StepsCountX || NoiseSampledSteps.Y != StepsCountY || NoiseSampledSteps.Z != StepsCountZ)
            {
                if (StepsCountX % NoiseSampledSteps.X != 0 ||
                    StepsCountY % NoiseSampledSteps.Y != 0 ||
                    StepsCountZ % NoiseSampledSteps.Z != 0)
                {
                    throw new Exception("NoiseSampling using NoiseSampledSteps that are not a multiple of StepsCount");
                }
                //CHECK for NoiseSampledSteps validity !
                needInterpolation = true;
            }

            int sampledStepCountX = NoiseSampledSteps.X;
            int sampledStepCountY = NoiseSampledSteps.Y;
            int sampledStepCountZ = NoiseSampledSteps.Z;

            if (needInterpolation)
            {
                sampledStepCountX++; // +1 If in Lerping Mode
                sampledStepCountY++; // +1 If in Lerping Mode
                sampledStepCountZ++; // +1 If in Lerping Mode
            }

            int NbrNoisesToParse = noiseFcts.Length;

            double[,] result = new double[(sampledStepCountX) * (sampledStepCountY) * (sampledStepCountZ), NbrNoisesToParse];

            double samplingStepDeltaX = (ToX - FromX) / (sampledStepCountX - 1);
            double samplingStepDeltaY = (ToY - FromY) / (sampledStepCountY - 1);
            double samplingStepDeltaZ = (ToZ - FromZ) / (sampledStepCountZ - 1);

            int    generatedNoise = 0;
            double valX, valY, valZ;

            //Sampled the Noise
            valX = FromX;
            for (int X = 0; X < sampledStepCountX; X++)
            {
                valZ = FromZ;
                for (int Z = 0; Z < sampledStepCountZ; Z++)
                {
                    valY = FromY;
                    for (int Y = 0; Y < sampledStepCountY; Y++)
                    {
                        for (int noiseId = 0; noiseId < NbrNoisesToParse; noiseId++)
                        {
                            result[generatedNoise, noiseId] = noiseFcts[noiseId].Get(valX, valY, valZ);
                        }

                        generatedNoise++;
                        valY += samplingStepDeltaY;
                    }
                    valZ += samplingStepDeltaZ;
                }
                valX += samplingStepDeltaX;
            }

            if (needInterpolation)
            {
                result = InterpolateResult(result, NoiseSampledSteps, new Vector3I(StepsCountX, StepsCountY, StepsCountZ));
            }

            return(result);
        }
Example #53
0
        private static void ComputeShapeBounds(IMyVoxelBase voxelMap, ref BoundingBoxD shapeAabb, Vector3D voxelMapMinCorner, Vector3I storageSize, out Vector3I voxelMin, out Vector3I voxelMax)
        {
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMapMinCorner, ref shapeAabb.Min, out voxelMin);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMapMinCorner, ref shapeAabb.Max, out voxelMax);

            MyVoxelBase voxelBase = voxelMap as MyVoxelBase;

            voxelMin += voxelBase.StorageMin;
            voxelMax += voxelBase.StorageMin + 1;

            storageSize -= 1;
            Vector3I.Clamp(ref voxelMin, ref Vector3I.Zero, ref storageSize, out voxelMin);
            Vector3I.Clamp(ref voxelMax, ref Vector3I.Zero, ref storageSize, out voxelMax);
        }
 public abstract void GetBlockPlacementMaterials(MyCubeBlockDefinition definition, Vector3I position, MyBlockOrientation orientation, MyCubeGrid grid);
Example #55
0
        public override void UpdateBeforeSimulation10()
        {
            base.UpdateBeforeSimulation10();

            if (!CheckUnobstructed())
            {
                if (SafeConstraint != null)
                {
                    RemoveConstraintInBoth();
                }
                return;
            }

            if (SafeConstraint != null)
            {
                bool staticOk = this.CubeGrid.IsStatic || !m_other.CubeGrid.IsStatic;
                if (!staticOk || !IsWorking || !m_other.IsWorking)
                {
                    return;
                }

                Debug.Assert(!m_other.CubeGrid.MarkedForClose && !CubeGrid.MarkedForClose);

                var   mergeBlockDefinition = this.BlockDefinition as MyMergeBlockDefinition;
                float maxStrength          = mergeBlockDefinition != null ? mergeBlockDefinition.Strength : 0.1f;
                float dist = (float)(WorldMatrix.Translation - m_other.WorldMatrix.Translation).Length() - CubeGrid.GridSize;

                if (dist > CubeGrid.GridSize * 3)
                {
                    RemoveConstraintInBoth();
                    return;
                }

                MergeData data = new MergeData();
                CalculateMergeData(ref data);

                (m_constraint.ConstraintData as HkMalleableConstraintData).Strength = data.ConstraintStrength;

                if (data.PositionOk && data.AxisOk && data.RotationOk)
                {
                    if (m_frameCounter++ >= 3)
                    {
                        Vector3I gridOffset      = CalculateOtherGridOffset();
                        Vector3I otherGridOffset = m_other.CalculateOtherGridOffset();

                        bool canMerge = this.CubeGrid.CanMergeCubes(m_other.CubeGrid, gridOffset);
                        if (!canMerge)
                        {
                            if (this.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled || m_other.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled)
                            {
                                MyHud.Notifications.Add(MyNotificationSingletons.ObstructingBlockDuringMerge);
                            }
                            return;
                        }
                        var handle = BeforeMerge;
                        if (handle != null)
                        {
                            BeforeMerge();
                        }
                        if (Sync.IsServer)
                        {
                            foreach (var block in CubeGrid.GetBlocks())
                            {
                                var mergeBlock = block.FatBlock as MyShipMergeBlock;
                                if (mergeBlock != null && mergeBlock != this && mergeBlock.InConstraint)
                                {
                                    (block.FatBlock as MyShipMergeBlock).RemoveConstraintInBoth();
                                }
                            }

                            MyCubeGrid mergedGrid = this.CubeGrid.MergeGrid_MergeBlock(m_other.CubeGrid, gridOffset);
                            if (mergedGrid == null)
                            {
                                mergedGrid = m_other.CubeGrid.MergeGrid_MergeBlock(this.CubeGrid, otherGridOffset);
                            }
                            Debug.Assert(mergedGrid != null);

                            RemoveConstraintInBoth();
                        }
                    }
                }
                else
                {
                    m_frameCounter = 0;
                }
                return;
            }
            foreach (var other in m_gridList)
            {
                if (other.MarkedForClose)
                {
                    continue;
                }
                Vector3I pos  = Vector3I.Zero;
                double   dist = double.MaxValue;
                LineD    l    = new LineD(Physics.ClusterToWorld(Physics.RigidBody.Position), Physics.ClusterToWorld(Physics.RigidBody.Position) + GetMergeNormalWorld());
                if (other.GetLineIntersectionExactGrid(ref l, ref pos, ref dist))
                {
                    var block = other.GetCubeBlock(pos).FatBlock as MyShipMergeBlock;
                    if (block == null || block.InConstraint || !block.IsWorking || !block.CheckUnobstructed() || block.GetMergeNormalWorld().Dot(GetMergeNormalWorld()) > 0.0f)
                    {
                        return;
                    }

                    if (!block.FriendlyWithBlock(this))
                    {
                        return;
                    }

                    CreateConstraint(other, block);

                    NeedsUpdate         |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
                    m_updateBeforeFlags |= UpdateBeforeFlags.EnableConstraint;
                    break;
                }
            }
        }
Example #56
0
 private static void GetVoxelShapeDimensions(IMyVoxelBase voxelMap, NaniteShape shape, out Vector3I minCorner, out Vector3I maxCorner, out Vector3I numCells)
 {
     {
         var bbox = shape.GetWorldBoundaries();
         ComputeShapeBounds(voxelMap, ref bbox, voxelMap.PositionLeftBottomCorner, voxelMap.Storage.Size, out minCorner, out maxCorner);
     }
     numCells = new Vector3I((maxCorner.X - minCorner.X) / CELL_SIZE, (maxCorner.Y - minCorner.Y) / CELL_SIZE, (maxCorner.Z - minCorner.Z) / CELL_SIZE);
 }
Example #57
0
 public override void OnMouseClick(VoxState s, FreeCamera camera, Vector2 mPos, MouseButton button, Viewport vp) {
     Ray r = camera.GetViewRay(mPos, vp.Width, vp.Height);
     if(button == MouseButton.Left) {
         VoxLocation? vl = VRayHelper.GetInner(r, s);
         if(vl.HasValue) {
             var loc = vl.Value;
             if(hasStart) {
                 Vector3I end = new Vector3I(
                     loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X,
                     loc.VoxelLoc.Y,
                     loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z
                     );
                 Vector3I min = new Vector3I(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z));
                 Vector3I max = new Vector3I(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z));
                 for(int ry = min.Y; ry <= max.Y; ry++) {
                     for(int rz = min.Z; rz <= max.Z; rz++) {
                         for(int rx = min.X; rx <= max.X; rx++) {
                             loc = new VoxLocation(new Vector3I(rx, ry, rz));
                             s.World.regions[loc.RegionIndex].RemoveVoxel(loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.VoxelLoc.Z);
                         }
                     }
                 }
                 hasStart = false;
             }
             else {
                 start = new Vector3I(
                     loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X,
                     loc.VoxelLoc.Y,
                     loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z
                     );
                 hasStart = true;
             }
         }
     }
     else if(button == MouseButton.Right) {
         VoxLocation? vl = VRayHelper.GetOuter(r, s);
         if(vl.HasValue) {
             var loc = vl.Value;
             if(hasStart) {
                 Vector3I end = new Vector3I(
                     loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X,
                     loc.VoxelLoc.Y,
                     loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z
                     );
                 Vector3I min = new Vector3I(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z));
                 Vector3I max = new Vector3I(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z));
                 for(int ry = min.Y; ry <= max.Y; ry++) {
                     for(int rz = min.Z; rz <= max.Z; rz++) {
                         for(int rx = min.X; rx <= max.X; rx++) {
                             loc = new VoxLocation(new Vector3I(rx, ry, rz));
                             s.World.regions[loc.RegionIndex].AddVoxel(loc.VoxelLoc.X, loc.VoxelLoc.Y, loc.VoxelLoc.Z, CurVoxID);
                         }
                     }
                 }
                 hasStart = false;
             }
             else {
                 start = new Vector3I(
                     loc.RegionLoc.X * Region.WIDTH + loc.VoxelLoc.X,
                     loc.VoxelLoc.Y,
                     loc.RegionLoc.Y * Region.DEPTH + loc.VoxelLoc.Z
                     );
                 hasStart = true;
             }
         }
     }
 }
Example #58
0
 public override bool ConnectionAllowed(ref Vector3I otherBlockMinPos, ref Vector3I otherBlockMaxPos, ref Vector3I faceNormal, MyCubeBlockDefinition def)
 {
     return(ConnectionAllowedInternal(ref faceNormal, def));
 }
Example #59
0
        public static void CalculateSamplePosition(ref Vector3 localPos, out Vector3I samplePosition, ref Vector2 texCoord, int resolution)
        {
            Vector3 abs = Vector3.Abs(localPos);

            if (abs.X > abs.Y)
            {
                if (abs.X > abs.Z)
                {
                    localPos  /= abs.X;
                    texCoord.Y = -localPos.Y;

                    if (localPos.X > 0.0f)
                    {
                        texCoord.X       = -localPos.Z;
                        samplePosition.X = (int)Faces.XPositive;
                    }
                    else
                    {
                        texCoord.X       = localPos.Z;
                        samplePosition.X = (int)Faces.XNegative;
                    }
                }
                else
                {
                    localPos  /= abs.Z;
                    texCoord.Y = -localPos.Y;
                    if (localPos.Z > 0.0f)
                    {
                        texCoord.X       = localPos.X;
                        samplePosition.X = (int)Faces.ZPositive;
                    }
                    else
                    {
                        texCoord.X       = -localPos.X;
                        samplePosition.X = (int)Faces.ZNegative;
                    }
                }
            }
            else
            {
                if (abs.Y > abs.Z)
                {
                    localPos  /= abs.Y;
                    texCoord.Y = -localPos.Z;
                    if (localPos.Y > 0.0f)
                    {
                        texCoord.X       = -localPos.X;
                        samplePosition.X = (int)Faces.YPositive;
                    }
                    else
                    {
                        texCoord.X       = localPos.X;
                        samplePosition.X = (int)Faces.YNegative;
                    }
                }
                else
                {
                    localPos  /= abs.Z;
                    texCoord.Y = -localPos.Y;
                    if (localPos.Z > 0.0f)
                    {
                        texCoord.X       = localPos.X;
                        samplePosition.X = (int)Faces.ZPositive;
                    }
                    else
                    {
                        texCoord.X       = -localPos.X;
                        samplePosition.X = (int)Faces.ZNegative;
                    }
                }
            }

            texCoord = ((texCoord + 1f) * .5f * resolution);

            samplePosition.Y = (int)Math.Round(texCoord.X);
            samplePosition.Z = (int)Math.Round(texCoord.Y);
        }
Example #60
0
        public void ProcessStrafing()
        {
            if (!this.AllowStrafing)
            {
                return;
            }

            if (this.Strafing == false)
            {
                TimeSpan duration = MyAPIGateway.Session.GameDateTime - this.LastStrafeEndTime;
                if (duration.TotalMilliseconds >= this.ThisStrafeCooldown)
                {
                    //Logger.MsgDebug("Begin Strafe", DebugTypeEnum.AutoPilot);
                    this.LastStrafeStartTime = MyAPIGateway.Session.GameDateTime;
                    this.ThisStrafeDuration  = Rnd.Next(StrafeMinDurationMs, StrafeMaxDurationMs);
                    this.Strafing            = true;

                    MyAPIGateway.Parallel.Start(() => {
                        _autoPilot.Collision.RunSecondaryCollisionChecks();
                        this.CurrentAllowedStrafeDirections = Vector3I.Zero;
                        this.CurrentStrafeDirections        = new Vector3I(Rnd.Next(-1, 2), Rnd.Next(-1, 2), Rnd.Next(-1, 2));

                        if (this.CurrentStrafeDirections.X != 0)
                        {
                            this.CurrentAllowedStrafeDirections.X = 1;
                            var rAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Right, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            var lAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Left, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            bool rTargetIntersect = (rAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);
                            bool lTargetIntersect = (lAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);

                            if (this.CurrentStrafeDirections.X == 1)
                            {
                                if (rTargetIntersect || (_collision.RightResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.LeftResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: X Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.X *= -1;
                                }
                                else if (lTargetIntersect || (_collision.RightResult.HasTarget(StrafeMinimumTargetDistance) && _collision.LeftResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: X Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.X = 0;
                                }
                            }
                            else
                            {
                                if (lTargetIntersect || (_collision.LeftResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.RightResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: X Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.X *= -1;
                                }
                                else if (rTargetIntersect || (_collision.LeftResult.HasTarget(StrafeMinimumTargetDistance) && _collision.RightResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: X Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.X = 0;
                                }
                            }
                        }

                        if (this.CurrentStrafeDirections.Y != 0)
                        {
                            this.CurrentAllowedStrafeDirections.Y = 1;
                            var uAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Up, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            var dAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Down, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            bool uTargetIntersect = (uAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);
                            bool dTargetIntersect = (dAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);

                            if (this.CurrentStrafeDirections.Y == 1)
                            {
                                if (uTargetIntersect || (_collision.UpResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.DownResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Y Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Y *= -1;
                                }
                                else if (dTargetIntersect || (_collision.UpResult.HasTarget(StrafeMinimumTargetDistance) && _collision.DownResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Y Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Y = 0;
                                }
                            }
                            else
                            {
                                if (dTargetIntersect || (_collision.DownResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.UpResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Y Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Y *= -1;
                                }
                                else if (uTargetIntersect || (_collision.DownResult.HasTarget(StrafeMinimumTargetDistance) && _collision.UpResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Y Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Y = 0;
                                }
                            }
                        }

                        if (this.CurrentStrafeDirections.Z != 0)
                        {
                            this.CurrentAllowedStrafeDirections.Z = 1;
                            var fAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Forward, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            var bAngle            = VectorHelper.GetAngleBetweenDirections(_collision.Matrix.Backward, Vector3D.Normalize(_autoPilot.GetCurrentWaypoint() - _collision.Matrix.Translation));
                            bool fTargetIntersect = (fAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);
                            bool bTargetIntersect = (bAngle < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance);

                            if (this.CurrentStrafeDirections.Z == 1)
                            {
                                if (fTargetIntersect || (_collision.ForwardResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.BackwardResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Z Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Z *= -1;
                                }
                                else if (bTargetIntersect || (_collision.ForwardResult.HasTarget(StrafeMinimumTargetDistance) && _collision.BackwardResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Z Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Z = 0;
                                }
                            }
                            else
                            {
                                if (bTargetIntersect || (_collision.BackwardResult.HasTarget(StrafeMinimumTargetDistance) && !_collision.ForwardResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Z Reverse", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Z *= -1;
                                }
                                else if (fTargetIntersect || (_collision.BackwardResult.HasTarget(StrafeMinimumTargetDistance) && _collision.ForwardResult.HasTarget(StrafeMinimumTargetDistance)))
                                {
                                    Logger.MsgDebug("Strafe: Z Negate", DebugTypeEnum.AutoPilot);
                                    this.CurrentStrafeDirections.Z = 0;
                                }
                            }
                        }

                        if (_autoPilot.UpDirectionFromPlanet != Vector3D.Zero && _autoPilot.MyAltitude < _autoPilot.MinimumPlanetAltitude)
                        {
                            var thrustDir = VectorHelper.GetThrustDirectionsAwayFromDirection(_collision.Matrix, -_autoPilot.UpDirectionFromPlanet);

                            if (thrustDir.X != 0)
                            {
                                this.CurrentAllowedStrafeDirections.X = 1;
                                this.CurrentStrafeDirections.X        = thrustDir.X;
                            }

                            if (thrustDir.Y != 0)
                            {
                                this.CurrentAllowedStrafeDirections.Y = 1;
                                this.CurrentStrafeDirections.Y        = thrustDir.Y;
                            }

                            if (thrustDir.Z != 0)
                            {
                                this.CurrentAllowedStrafeDirections.Z = 1;
                                this.CurrentStrafeDirections.Z        = thrustDir.Z;
                            }
                        }
                    }, () => {
                        SetThrust(this.CurrentAllowedStrafeDirections, this.CurrentStrafeDirections);
                    });
                }
            }
            else
            {
                TimeSpan duration = MyAPIGateway.Session.GameDateTime - this.LastStrafeStartTime;

                if (duration.TotalMilliseconds >= this.ThisStrafeDuration)
                {
                    //Logger.MsgDebug("End Strafe", DebugTypeEnum.General);
                    this.InvertStrafingActivated = false;
                    this.LastStrafeEndTime       = MyAPIGateway.Session.GameDateTime;
                    this.ThisStrafeCooldown      = Rnd.Next(StrafeMinCooldownMs, StrafeMaxCooldownMs);
                    this.Strafing                   = false;
                    _collisionStrafeAdjusted        = false;
                    _minAngleDistanceStrafeAdjusted = false;
                    _collisionStrafeDirection       = Vector3D.Zero;
                    SetThrust(new Vector3I(0, 0, 0), new Vector3I(0, 0, 0));
                    //Logger.AddMsg("Cooldown: " + this.ThisStrafeCooldown.ToString(), true);
                }
                else
                {
                    //Logger.MsgDebug("Strafe Collision: " + _collision.VelocityResult.CollisionImminent.ToString() + " - " + _collision.VelocityResult.Time.ToString(), DebugTypeEnum.Collision);

                    if (!_collisionStrafeAdjusted && _collision.VelocityResult.CollisionImminent())
                    {
                        Logger.MsgDebug("Strafe Velocity Collision Detect: " + _collision.VelocityResult.Type.ToString() + ", " + _collision.VelocityResult.GetCollisionDistance(), DebugTypeEnum.Collision);
                        _collisionStrafeAdjusted = true;
                        StopStrafeDirectionNearestPosition(_collision.VelocityResult.GetCollisionCoords());
                        _collisionStrafeDirection = Vector3D.Normalize(_collision.VelocityResult.GetCollisionCoords() - RemoteControl.WorldMatrix.Translation);
                    }
                    else if (_collisionStrafeAdjusted && VectorHelper.GetAngleBetweenDirections(_collisionStrafeDirection, Vector3D.Normalize(_collision.Velocity - RemoteControl.WorldMatrix.Translation)) > 15)
                    {
                        Logger.MsgDebug("Strafe Collision Detect", DebugTypeEnum.General);
                        StopStrafeDirectionNearestPosition(_collision.VelocityResult.GetCollisionCoords());
                        _collisionStrafeDirection = Vector3D.Normalize(_collision.VelocityResult.GetCollisionCoords() - RemoteControl.WorldMatrix.Translation);
                    }

                    if (_minAngleDistanceStrafeAdjusted && _autoPilot.AngleToCurrentWaypoint < this.StrafeMinimumSafeAngleFromTarget && _autoPilot.DistanceToCurrentWaypoint < this.StrafeMinimumTargetDistance)
                    {
                        Logger.MsgDebug("Strafe Min Dist/Angle Detect", DebugTypeEnum.General);
                        _minAngleDistanceStrafeAdjusted = false;
                        StopStrafeDirectionNearestPosition(_collision.VelocityResult.GetCollisionCoords());
                        _collisionStrafeDirection = Vector3D.Normalize(_collision.VelocityResult.GetCollisionCoords() - RemoteControl.WorldMatrix.Translation);
                    }
                }
            }
        }