Пример #1
0
 public Vec3d Set(Vec3i pos)
 {
     this.X = pos.X;
     this.Y = pos.Y;
     this.Z = pos.Z;
     return(this);
 }
Пример #2
0
        private BlockFacing(string code, byte flag, int index, int oppositeIndex, int horizontalAngleIndex, Vec3i facingVector, Vec3f planeCenter, EnumAxis axis, Cuboidf plane)
        {
            this.index                = index;
            this.meshDataIndex        = (byte)(index + 1);
            this.horizontalAngleIndex = horizontalAngleIndex;
            this.flag          = flag;
            this.code          = code;
            this.oppositeIndex = oppositeIndex;
            this.normali       = facingVector;
            this.normalf       = new Vec3f(facingVector.X, facingVector.Y, facingVector.Z);
            this.normald       = new Vec3d((double)facingVector.X, (double)facingVector.Y, (double)facingVector.Z);
            this.plane         = plane;

            normalPacked = NormalUtil.PackNormal(normalf.X, normalf.Y, normalf.Z);
            normalb      = (byte)(
                (axis == EnumAxis.Z ? 1 : 0) << 0
                    | (facingVector.Z < 0 ? 1 : 0) << 1

                    | (axis == EnumAxis.Y ? 1 : 0) << 2
                    | (facingVector.Y < 0 ? 1 : 0) << 3

                    | (axis == EnumAxis.X ? 1 : 0) << 4
                    | (facingVector.X < 0 ? 1 : 0) << 5
                );

            normalPackedFlags = VertexFlags.PackNormal(normalf);

            this.planeCenter = planeCenter;
            this.axis        = axis;
        }
Пример #3
0
        private BlockFacing GetExitingFullBlockFace(BlockPos pos, ref Vec3d exitPos)
        {
            for (int i = 0; i < BlockFacing.NumberOfFaces; i++)
            {
                BlockFacing blockSideFacing = BlockFacing.ALLFACES[i];
                Vec3i       planeNormal     = blockSideFacing.Normali;

                double demon = planeNormal.X * ray.dir.X + planeNormal.Y * ray.dir.Y + planeNormal.Z * ray.dir.Z;

                if (demon > 0.00001)
                {
                    Vec3d planePosition = pos.ToVec3d().Add(blockSideFacing.PlaneCenter);

                    Vec3d  pt = Vec3d.Sub(planePosition, ray.origin);
                    double t  = (pt.X * planeNormal.X + pt.Y * planeNormal.Y + pt.Z * planeNormal.Z) / demon;

                    if (t >= 0)
                    {
                        Vec3d pHit = new Vec3d(ray.origin.X + ray.dir.X * t, ray.origin.Y + ray.dir.Y * t, ray.origin.Z + ray.dir.Z * t);
                        exitPos = Vec3d.Sub(pHit, planePosition);

                        if (Math.Abs(exitPos.X) <= 0.5 && Math.Abs(exitPos.Y) <= 0.5 && Math.Abs(exitPos.Z) <= 0.5)
                        {
                            return(blockSideFacing);
                        }
                    }
                }
            }

            return(null);
        }
Пример #4
0
        public static Vec3i[] GenCubicShellVectors(int r)
        {
            int[]   ab      = new int[2];
            Vec3i[] vectors = new Vec3i[(2 * r + 1) * (2 * r + 1) * 6];
            int     j       = 0;

            foreach (BlockFacing facing in BlockFacing.ALLFACES)
            {
                for (ab[0] = -r; ab[0] <= r; ab[0]++)
                {
                    for (ab[1] = -r; ab[1] <= r; ab[1]++)
                    {
                        Vec3i pos = new Vec3i(facing.Normali.X * r, facing.Normali.Y * r, facing.Normali.Z * r);
                        int   l   = 0;
                        if (pos.X == 0)
                        {
                            pos.X = ab[l++];
                        }
                        if (pos.Y == 0)
                        {
                            pos.Y = ab[l++];
                        }
                        if (l < 2 && pos.Z == 0)
                        {
                            pos.Z = ab[l++];
                        }

                        vectors[j++] = pos;
                    }
                }
            }

            return(vectors);
        }
Пример #5
0
 public BlockPos Set(Vec3i pos)
 {
     X = pos.X;
     Y = pos.Y;
     Z = pos.Z;
     return(this);
 }
Пример #6
0
        public static Cardinal FromNormali(Vec3i normali)
        {
            Cardinal card;

            byNormali.TryGetValue(normali, out card);
            return(card);
        }
Пример #7
0
 /// <summary>
 /// Offsets the position by given xyz vector
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 public BlockPos Add(Vec3i vector)
 {
     X += vector.X;
     Y += vector.Y;
     Z += vector.Z;
     return(this);
 }
Пример #8
0
        public static void PosInt3d(long index, long sizex, long sizez, Vec3i ret)
        {
            int x = (int)(index % sizex);
            int y = (int)(index / (sizex * sizez));
            int z = (int)((index / sizex) % sizez);

            ret.X = x;
            ret.Y = y;
            ret.Z = z;
        }
Пример #9
0
        public static void PosInt3d(int index, long sizex, long sizez, Vec3i ret)
        {
            long x = index % sizex;
            long y = index / (sizex * sizez);
            long z = (index / sizex) % sizez;

            ret.X = (int)x;
            ret.Y = (int)y;
            ret.Z = (int)z;
        }
Пример #10
0
        public static BlockFacing FromNormal(Vec3i vec)
        {
            Cardinal c = Cardinal.FromNormali(vec);

            if (c == null)
            {
                return(null);
            }
            return(FromFirstLetter(c.Initial));
        }
Пример #11
0
 public Cardinal(string code, string initial, Vec3i normali, int index, int oppositeIndex, bool isDiagonal)
 {
     this.Code          = code;
     this.Initial       = initial;
     this.Normali       = normali;
     this.Index         = index;
     this.IsDiagnoal    = isDiagonal;
     this.OppositeIndex = oppositeIndex;
     byNormali.Add(normali, this);
     byInitial.Add(initial, this);
 }
Пример #12
0
        public static BlockFacing FromNormal(Vec3i vec)
        {
            for (int i = 0; i < ALLFACES.Length; i++)
            {
                BlockFacing f = ALLFACES[i];
                if (f.normali.Equals(vec))
                {
                    return(f);
                }
            }

            return(null);
        }
Пример #13
0
        public bool RayIntersectsWithCuboid(Cuboidd selectionBox, ref BlockFacing hitOnBlockFace, ref Vec3d hitPosition)
        {
            if (selectionBox == null)
            {
                return(false);
            }

            double w = selectionBox.X2 - selectionBox.X1;
            double h = selectionBox.Y2 - selectionBox.Y1;
            double l = selectionBox.Z2 - selectionBox.Z1;

            for (int i = 0; i < BlockFacing.NumberOfFaces; i++)
            {
                BlockFacing blockSideFacing = BlockFacing.ALLFACES[i];
                Vec3i       planeNormal     = blockSideFacing.Normali;

                // Dot product of 2 vectors
                // If they are parallel the dot product is 1
                // At 90 degrees the dot product is 0
                double demon = planeNormal.X * ray.dir.X + planeNormal.Y * ray.dir.Y + planeNormal.Z * ray.dir.Z;

                // Does intersect this plane somewhere (only negative because we are not interested in the ray leaving a face, negative because the ray points into the cube, the plane normal points away from the cube)
                if (demon < -0.00001)
                {
                    Vec3d planeCenterPosition = blockSideFacing.PlaneCenter
                                                .ToVec3d()
                                                .Mul(w, h, l)
                                                .Add(selectionBox.X1, selectionBox.Y1, selectionBox.Z1)
                    ;

                    Vec3d  pt = Vec3d.Sub(planeCenterPosition, ray.origin);
                    double t  = (pt.X * planeNormal.X + pt.Y * planeNormal.Y + pt.Z * planeNormal.Z) / demon;

                    if (t >= 0)
                    {
                        hitPosition            = new Vec3d(ray.origin.X + ray.dir.X * t, ray.origin.Y + ray.dir.Y * t, ray.origin.Z + ray.dir.Z * t);
                        lastExitedBlockFacePos = Vec3d.Sub(hitPosition, planeCenterPosition);

                        // Does intersect this plane within the block
                        if (Math.Abs(lastExitedBlockFacePos.X) <= w / 2 && Math.Abs(lastExitedBlockFacePos.Y) <= h / 2 && Math.Abs(lastExitedBlockFacePos.Z) <= l / 2)
                        {
                            hitOnBlockFace = blockSideFacing;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Пример #14
0
        public bool RayIntersectsBlockSelectionBox(BlockPos pos, BlockFilter filter)
        {
            if (filter?.Invoke(pos, blockSelectionTester.GetBlock(pos)) == false)
            {
                return(false);
            }

            Cuboidf[] selectionBoxes = blockSelectionTester.GetBlockIntersectionBoxes(pos);
            if (selectionBoxes == null)
            {
                return(false);
            }

            bool intersects = false;
            bool wasDecor   = false;

            for (int i = 0; i < selectionBoxes.Length; i++)
            {
                tmpCuboidd.Set(selectionBoxes[i]).Translate(pos.X, pos.Y, pos.Z);
                if (RayIntersectsWithCuboid(tmpCuboidd, ref hitOnBlockFaceTmp, ref hitPositionTmp))
                {
                    bool isDecor = selectionBoxes[i] is DecorSelectionBox;
                    if (intersects && (!wasDecor || isDecor) && hitPosition.SquareDistanceTo(ray.origin) <= hitPositionTmp.SquareDistanceTo(ray.origin))
                    {
                        continue;
                    }

                    hitOnSelectionBox = i;
                    intersects        = true;
                    wasDecor          = isDecor;
                    hitOnBlockFace    = hitOnBlockFaceTmp;
                    hitPosition.Set(hitPositionTmp);
                }
            }

            if (intersects && selectionBoxes[hitOnSelectionBox] is DecorSelectionBox dsb)
            {
                Vec3i posAdjust = dsb.PosAdjust;
                if (posAdjust != null)
                {
                    pos.Add(posAdjust);
                }
            }

            return(intersects);
        }
Пример #15
0
 public Vec3f(Vec3i vec3i)
 {
     this.X = vec3i.X;
     this.Y = vec3i.Y;
     this.Z = vec3i.Z;
 }
Пример #16
0
 public Cuboidi(Vec3i startPos, Vec3i endPos)
 {
     Set(startPos.X, startPos.Y, startPos.Z, endPos.X, endPos.Y, endPos.Z);
 }
Пример #17
0
 /// <summary>
 /// Creates a copy of this blocks position and offsets it by given xyz
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 public BlockPos AddCopy(Vec3i vector)
 {
     return(new BlockPos(X + vector.X, Y + vector.Y, Z + vector.Z));
 }
Пример #18
0
 public BlockPos(Vec3i vec)
 {
     this.X = vec.X;
     this.Y = vec.Y;
     this.Z = vec.Z;
 }