Beispiel #1
0
        public Vec4d TransformVector(Vec4d vec)
        {
            Vec4d outval = new Vec4d();

            Mat4f.MulWithVec4(Values, vec, outval);
            return(outval);
        }
Beispiel #2
0
        public static Point3d TransformPoint3d(this Mat pose, Point3d point)
        {
            if (pose.Cols != 4 || pose.Rows != 4)
            {
                throw new ArgumentException("Matrix must be a 4 x 4 matrix");
            }

            if (pose.Type() != MatType.CV_64FC1)
            {
                throw new ArgumentException("Matrix must be of float 32 bit type");
            }

            var m1   = new float[4, 4];
            var data = new float[16];

            pose.GetArray(out data);
            Array.Copy(data, m1, data.Length);

            var v1 = new double[4] {
                point.X, point.Y, point.Z, 1
            };

            var homogenous = new Vec4d(
                (m1[0, 0] * v1[0] + m1[0, 1] * v1[1] + m1[0, 2] * v1[2] + m1[0, 3] * v1[3]),
                (m1[1, 0] * v1[0] + m1[1, 1] * v1[1] + m1[1, 2] * v1[2] + m1[1, 3] * v1[3]),
                (m1[2, 0] * v1[0] + m1[2, 1] * v1[1] + m1[2, 2] * v1[2] + m1[2, 3] * v1[3]),
                (m1[3, 0] * v1[0] + m1[3, 1] * v1[1] + m1[3, 2] * v1[2] + m1[3, 3] * v1[3])
                );

            return(new Point3d(homogenous.Item0, homogenous.Item1, homogenous.Item2));
        }
Beispiel #3
0
        public bool OnInteract(IPlayer byPlayer, BlockSelection blockSel)
        {
            ItemSlot handslot = byPlayer.InventoryManager.ActiveHotbarSlot;

            Vec4d    vec        = new Vec4d(blockSel.HitPosition.X, blockSel.HitPosition.Y, blockSel.HitPosition.Z, 1);
            Vec4d    tvec       = mat.TransformVector(vec);
            int      a          = Facing.Axis == EnumAxis.Z ? 1 : 0;
            ItemSlot targetSlot = tvec.X < 0.5 ? inv[a] : inv[1 - a];

            if (handslot.Empty)
            {
                TryTake(targetSlot, byPlayer);
            }
            else
            {
                if (TryAddPart(handslot, byPlayer))
                {
                    return(true);
                }

                if (handslot.Itemstack.Collectible.CrushingProps != null)
                {
                    TryPut(handslot, targetSlot);
                }
            }

            return(true);
        }
        public bool OnInteract(IPlayer byPlayer, BlockSelection blockSel)
        {
            ItemSlot handslot = byPlayer.InventoryManager.ActiveHotbarSlot;

            Vec4d    vec        = new Vec4d(blockSel.HitPosition.X, blockSel.HitPosition.Y, blockSel.HitPosition.Z, 1);
            Vec4d    tvec       = mat.TransformVector(vec);
            int      a          = Facing.Axis == EnumAxis.Z ? 1 : 0;
            ItemSlot targetSlot = tvec.X < 0.5 ? inv[a] : inv[1 - a];

            if (handslot.Empty)
            {
                TryTake(targetSlot, byPlayer);
            }
            else
            {
                if (TryAddPart(handslot, byPlayer))
                {
                    var pos = Pos.ToVec3d().Add(0.5, 0.25, 0.5);
                    Api.World.PlaySoundAt(Block.Sounds.Place, pos.X, pos.Y, pos.Z, byPlayer);
                    (Api as ICoreClientAPI)?.World.Player.TriggerFpAnimation(EnumHandInteract.HeldItemInteract);
                    return(true);
                }

                if (handslot.Itemstack.Collectible.CrushingProps != null)
                {
                    TryPut(handslot, targetSlot);
                }
            }

            return(true);
        }
Beispiel #5
0
        static void Main(string[] args)
        {
            Vec4d vector1 = new Vec4d(1.0, 2.0, 3.0, 4.0);
            Vec4d vector2 = new Vec4d(1.0, 2.0, 3.0, 4.0);

            Console.WriteLine(vector1.Item0);
            Console.WriteLine(vector1[1]);
            Console.WriteLine(vector1.Equals(vector2));
        }
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public static Vec4d Apply(this Transform xform, Vec4d vector)
 {
     return(new Vec4d(
                vector.X * xform.M00 + vector.Y * xform.M01 + vector.Z * xform.M02 + vector.W * xform.M03,
                vector.X * xform.M10 + vector.Y * xform.M11 + vector.Z * xform.M12 + vector.W * xform.M13,
                vector.X * xform.M20 + vector.Y * xform.M21 + vector.Z * xform.M22 + vector.W * xform.M23,
                vector.W
                ));
 }
Beispiel #7
0
        /// <summary>
        /// Multiply the matrix with a vec4. Reference: http://mathinsight.org/matrix_vector_multiplication
        ///
        /// </summary>
        /// <param name="matrix"></param>
        /// <param name="inVal"></param>
        /// <param name="outVal"></param>
        /// <returns></returns>
        public static void MulWithVec4(double[] matrix, Vec4d inVal, Vec4d outVal)
        {
            outVal.Set(0, 0, 0, 0);

            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 4; col++)
                {
                    outVal[row] += matrix[4 * col + row] * inVal[col];
                }
            }
        }
Beispiel #8
0
        public void WriteFrames4d(BinaryWriter writer, byte frame_t, SortedList <int, object> frames)
        {
            WriteFrameT(writer, frame_t, frames.Count);

            foreach (KeyValuePair <int, object> pair in frames)
            {
                Vec4d value = (Vec4d)pair.Value;
                WriteFrameT(writer, frame_t, pair.Key);
                writer.Write(value.x);
                writer.Write(value.y);
                writer.Write(value.z);
                writer.Write(value.w);
            }
        }
Beispiel #9
0
        public static Vec4d UnpackRotation(ushort a, ushort b, ushort c)
        {
            Vec4d q = new Vec4d();

            int axis1 = a >> 15;
            int axis2 = b >> 15;
            int axis  = axis2 << 1 | axis1;

            a = (ushort)(a & 0x7FFF);
            b = (ushort)(b & 0x7FFF);

            double x, y, z, w;

            x = 1.41421 * (a - 0x4000) / 0x8000;
            y = 1.41421 * (b - 0x4000) / 0x8000;
            z = 1.41421 * (c - 0x8000) / 0x10000;

            w = Math.Pow(1.0 - x * x - y * y - z * z, 0.5);

            // Console.Out.WriteLine("Unpack Values: X: {0}, Y: {1}, Z: {2}, W: {3}, Axis: {4}", x, y, z, w, axis);

            if (axis == 0)
            {
                q = new Vec4d(w, x, y, z);
            }
            else if (axis == 1)
            {
                q = new Vec4d(x, w, y, z);
            }
            else if (axis == 2)
            {
                q = new Vec4d(x, y, w, z);
            }
            else if (axis == 3)
            {
                q = new Vec4d(x, y, z, w);
            }
            else
            {
                Console.Out.WriteLine("Unknown Axis detected! Axis: %s", axis);
            }

            return(q);
        }
Beispiel #10
0
        public Animation(Stream animStream, bool leaveOpen = true, bool alwaysAddBones = false)
        {
            Animations = new List <Keyframe>();
            // Convert OW Animation to our Animation Type
            using (BinaryReader animReader = new BinaryReader(animStream, Encoding.Default, leaveOpen)) {
                Header = animReader.Read <AnimHeader>();

                Duration        = Header.duration;
                FramesPerSecond = Header.fps;
                InfoTableSize   = (int)(Header.fps * Header.duration) + 1;
                ushort bonecount = Header.bonecount;

                animStream.Seek((long)Header.boneListOffset, SeekOrigin.Begin);
                for (uint i = 0; i < Header.bonecount; i++)
                {
                    int boneID = animReader.ReadInt32();
                    BoneList.Add(boneID);
                }

                Vec3d[,] ScaleValues    = new Vec3d[bonecount, InfoTableSize];
                Vec3d[,] PositionValues = new Vec3d[bonecount, InfoTableSize];
                Vec4d[,] RotationValues = new Vec4d[bonecount, InfoTableSize];
                bool[,] hasScale        = new bool[bonecount, InfoTableSize];
                bool[,] hasPosition     = new bool[bonecount, InfoTableSize];
                bool[,] hasRotation     = new bool[bonecount, InfoTableSize];

                animStream.Seek((long)Header.infoTableOffset, SeekOrigin.Begin);
                for (int boneid = 0; boneid < Header.bonecount; boneid++)
                {
                    long          animStreamPos = animStream.Position;
                    AnimInfoTable it            = animReader.Read <AnimInfoTable>();
                    long          SIO           = (long)it.ScaleIndicesOffset * 4 + animStreamPos;
                    long          PIO           = (long)it.PositionIndicesOffset * 4 + animStreamPos;
                    long          RIO           = (long)it.RotationIndicesOffset * 4 + animStreamPos;
                    long          SDO           = (long)it.ScaleDataOffset * 4 + animStreamPos;
                    long          PDO           = (long)it.PositionDataOffset * 4 + animStreamPos;
                    long          RDO           = (long)it.RotationDataOffset * 4 + animStreamPos;
                    InfoTables.Add(it);

                    // Read Indices
                    List <int> ScaleIndexList = new List <int>();
                    animStream.Seek(SIO, SeekOrigin.Begin);
                    for (int j = 0; j < it.ScaleCount; j++)
                    {
                        if (InfoTableSize <= 255)
                        {
                            ScaleIndexList.Add((int)animReader.ReadByte());
                        }
                        else
                        {
                            ScaleIndexList.Add((int)animReader.ReadInt16());
                        }
                    }
                    List <int> PositonIndexList = new List <int>();
                    animStream.Seek(PIO, SeekOrigin.Begin);
                    for (int j = 0; j < it.PositionCount; j++)
                    {
                        if (InfoTableSize <= 255)
                        {
                            PositonIndexList.Add((int)animReader.ReadByte());
                        }
                        else
                        {
                            PositonIndexList.Add((int)animReader.ReadInt16());
                        }
                    }
                    List <int> RotationIndexList = new List <int>();
                    animStream.Seek(RIO, SeekOrigin.Begin);
                    for (int j = 0; j < it.RotationCount; j++)
                    {
                        if (InfoTableSize <= 255)
                        {
                            RotationIndexList.Add((int)animReader.ReadByte());
                        }
                        else
                        {
                            RotationIndexList.Add((int)animReader.ReadInt16());
                        }
                    }
                    // Read Data
                    animStream.Seek(SDO, SeekOrigin.Begin);
                    for (int j = 0; j < it.ScaleCount; j++)
                    {
                        int Index = Math.Abs(ScaleIndexList[j]) % InfoTableSize;
                        hasScale[boneid, Index] = true;
                        ushort x = animReader.ReadUInt16();
                        ushort y = animReader.ReadUInt16();
                        ushort z = animReader.ReadUInt16();

                        Vec3d values = UnpackScale(x, y, z);
                        ScaleValues[boneid, Index] = values;
                    }
                    animStream.Seek(PDO, SeekOrigin.Begin);
                    for (int j = 0; j < it.PositionCount; j++)
                    {
                        int Index = Math.Abs(PositonIndexList[j]) % InfoTableSize;
                        hasPosition[boneid, Index] = true;
                        float x = animReader.ReadSingle();
                        float y = animReader.ReadSingle();
                        float z = animReader.ReadSingle();

                        Vec3d values = new Vec3d(x, y, z);
                        PositionValues[boneid, Index] = values;
                    }
                    animStream.Seek(RDO, SeekOrigin.Begin);
                    for (int j = 0; j < it.RotationCount; j++)
                    {
                        int    Index = Math.Abs(RotationIndexList[j]) % InfoTableSize;
                        ushort x     = animReader.ReadUInt16();
                        ushort y     = animReader.ReadUInt16();
                        ushort z     = animReader.ReadUInt16();

                        Vec4d values = UnpackRotation(x, y, z);
                        hasRotation[boneid, Index]    = true;
                        RotationValues[boneid, Index] = values;
                    }
                    animStream.Seek(animStreamPos + 32L, SeekOrigin.Begin);
                }


                for (int frame = 0; frame < InfoTableSize; frame++)
                {
                    Keyframe kf = new Keyframe();
                    kf.FramePosition  = ((float)frame / FramesPerSecond);
                    kf.FramePositionI = frame;
                    kf.BoneFrames     = new List <BoneAnimation>();
                    for (int bone = 0; bone < Header.bonecount; bone++)
                    {
                        // Build Value Data
                        BoneAnimation ba = new BoneAnimation();
                        ba.BoneID = BoneList[bone];
                        ba.Values = new List <FrameValue>();

                        if (hasScale[bone, frame])
                        {
                            Vec3d      v  = ScaleValues[bone, frame];
                            FrameValue fv = new FrameValue(AnimChannelID.SCALE, v);
                            ba.Values.Add(fv);
                        }
                        if (hasPosition[bone, frame])
                        {
                            Vec3d      v = PositionValues[bone, frame];
                            FrameValue f = new FrameValue(AnimChannelID.POSITION, v);
                            ba.Values.Add(f);
                        }
                        if (hasRotation[bone, frame])
                        {
                            Vec4d      v = RotationValues[bone, frame];
                            FrameValue f = new FrameValue(AnimChannelID.ROTATION, v);
                            ba.Values.Add(f);
                        }
                        if (ba.Values.Count > 0 || alwaysAddBones)
                        {
                            kf.BoneFrames.Add(ba);
                        }
                    }
                    if (kf.BoneFrames.Count > 0)
                    {
                        Animations.Add(kf);
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Reconstructs points by triangulation.
        /// </summary>
        /// <param name="projMatr1">3x4 projection matrix of the first camera.</param>
        /// <param name="projMatr2">3x4 projection matrix of the second camera.</param>
        /// <param name="projPoints1">2xN array of feature points in the first image. In case of c++ version 
        /// it can be also a vector of feature points or two-channel matrix of size 1xN or Nx1.</param>
        /// <param name="projPoints2">2xN array of corresponding points in the second image. In case of c++ version 
        /// it can be also a vector of feature points or two-channel matrix of size 1xN or Nx1.</param>
        /// <returns>4xN array of reconstructed points in homogeneous coordinates.</returns>
        public static Vec4d[] TriangulatePoints(
            double[,] projMatr1, double[,] projMatr2,
            IEnumerable<Point2d> projPoints1, IEnumerable<Point2d> projPoints2)
        {
            if (projMatr1 == null)
                throw new ArgumentNullException("projMatr1");
            if (projMatr2 == null)
                throw new ArgumentNullException("projMatr2");
            if (projPoints1 == null)
                throw new ArgumentNullException("projPoints1");
            if (projPoints2 == null)
                throw new ArgumentNullException("projPoints2");
            if (projMatr1.GetLength(0) != 3 && projMatr1.GetLength(1) != 4)
                throw new ArgumentException("projMatr1 != double[3,4]");
            if (projMatr2.GetLength(0) != 3 && projMatr2.GetLength(1) != 4)
                throw new ArgumentException("projMatr2 != double[3,4]");
            
            Point2d[] projPoints1Array = EnumerableEx.ToArray(projPoints1);
            Point2d[] projPoints2Array = EnumerableEx.ToArray(projPoints2);
            var points4D = new Vec4d[projPoints1Array.Length];

            NativeMethods.calib3d_triangulatePoints_array(
                projMatr1, projMatr2,
                projPoints1Array, projPoints1Array.Length,
                projPoints2Array, projPoints2Array.Length,
                points4D);

            return points4D;
        }
 public static extern ExceptionStatus core_Mat_push_back_Vec4d(IntPtr self, Vec4d v);
        // Requirements:
        // - ✔ Try to not move a lot vertically
        // - ✔ If territorial: Stay close to the spawn point
        // - ✔ If air habitat: Don't go above maxHeight blocks above surface
        // - ✔ If land habitat: Don't walk into water, prefer surface
        // - ~~If cave habitat: Prefer caves~~
        // - ✔ If water habitat: Don't walk onto land
        // - ✔ Try not to fall from very large heights. Try not to fall from any large heights if entity has FallDamage
        // - ✔ Prefer preferredLightLevel
        // - ✔ If land habitat: Must be above a block the entity can stand on
        // - ✔ if failed searches is high, reduce wander range
        public Vec3d loadNextWanderTarget()
        {
            EnumHabitat habitat       = entity.Properties.Habitat;
            bool        canFallDamage = entity.Properties.FallDamage;
            bool        territorial   = StayCloseToSpawn;
            int         tries         = 9;
            Vec4d       bestTarget    = null;
            Vec4d       curTarget     = new Vec4d();
            BlockPos    tmpPos        = new BlockPos();

            if (FailedConsecutivePathfinds > 10)
            {
                WanderRangeMul = Math.Max(0.1f, WanderRangeMul * 0.9f);
            }
            else
            {
                WanderRangeMul = Math.Min(1, WanderRangeMul * 1.1f);
                if (rand.NextDouble() < 0.05)
                {
                    WanderRangeMul = Math.Min(1, WanderRangeMul * 1.5f);
                }
            }

            float  wRangeMul = WanderRangeMul;
            double dx, dy, dz;

            if (rand.NextDouble() < 0.05)
            {
                wRangeMul *= 3;
            }

            while (tries-- > 0)
            {
                dx = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dy = wanderRangeVertical.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dz = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;

                curTarget.X = entity.ServerPos.X + dx;
                curTarget.Y = entity.ServerPos.Y + dy;
                curTarget.Z = entity.ServerPos.Z + dz;
                curTarget.W = 1;

                if (StayCloseToSpawn)
                {
                    double distToEdge = curTarget.SquareDistanceTo(SpawnPosition) / (MaxDistanceToSpawn * MaxDistanceToSpawn);
                    // Prefer staying close to spawn
                    curTarget.W = 1 - distToEdge;
                }

                Block block;


                switch (habitat)
                {
                case EnumHabitat.Air:
                    int rainMapY = world.BlockAccessor.GetRainMapHeightAt((int)curTarget.X, (int)curTarget.Z);
                    // Don't fly above max height
                    curTarget.Y = Math.Min(curTarget.Y, rainMapY + maxHeight);

                    // Cannot be in water
                    block = entity.World.BlockAccessor.GetBlock((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                    if (block.IsLiquid())
                    {
                        curTarget.W = 0;
                    }
                    break;

                case EnumHabitat.Land:
                    curTarget.Y = moveDownToFloor((int)curTarget.X, curTarget.Y, (int)curTarget.Z);
                    // No floor found
                    if (curTarget.Y < 0)
                    {
                        curTarget.W = 0;
                    }
                    else
                    {
                        // Does not like water
                        block = entity.World.BlockAccessor.GetBlock((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                        if (block.IsLiquid())
                        {
                            curTarget.W /= 2;
                        }

                        // Lets make a straight line plot to see if we would fall off a cliff
                        bool stop     = false;
                        bool willFall = false;

                        float angleHor          = (float)Math.Atan2(dx, dz) + GameMath.PIHALF;
                        Vec3d target1BlockAhead = curTarget.XYZ.Ahead(1, 0, angleHor);
                        Vec3d startAhead        = entity.ServerPos.XYZ.Ahead(1, 0, angleHor); // Otherwise they are forever stuck if they stand over the edge

                        int prevY = (int)startAhead.Y;

                        GameMath.BresenHamPlotLine2d((int)startAhead.X, (int)startAhead.Z, (int)target1BlockAhead.X, (int)target1BlockAhead.Z, (x, z) =>
                        {
                            if (stop)
                            {
                                return;
                            }

                            double nowY = moveDownToFloor(x, prevY, z);

                            // Not more than 4 blocks down
                            if (nowY < 0 || prevY - nowY > 4)
                            {
                                willFall = true;
                                stop     = true;
                            }

                            // Not more than 2 blocks up
                            if (nowY - prevY > 2)
                            {
                                stop = true;
                            }

                            prevY = (int)nowY;
                        });

                        if (willFall)
                        {
                            curTarget.W = 0;
                        }
                    }
                    break;

                case EnumHabitat.Sea:
                    block = entity.World.BlockAccessor.GetBlock((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                    if (!block.IsLiquid())
                    {
                        curTarget.W = 0;
                    }
                    break;
                }

                if (curTarget.W > 0)
                {
                    // Try to not hug the wall so much
                    for (int i = 0; i < BlockFacing.HORIZONTALS.Length; i++)
                    {
                        BlockFacing face = BlockFacing.HORIZONTALS[i];
                        block = entity.World.BlockAccessor.GetBlock((int)curTarget.X + face.Normali.X, (int)curTarget.Y, (int)curTarget.Z + face.Normali.Z);
                        if (block.SideSolid[face.Opposite.Index])
                        {
                            curTarget.W *= 0.5;
                        }
                    }
                }


                if (preferredLightLevel != null)
                {
                    tmpPos.Set((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                    int lightdiff = Math.Abs((int)preferredLightLevel - entity.World.BlockAccessor.GetLightLevel(tmpPos, EnumLightLevelType.MaxLight));

                    curTarget.W /= Math.Max(1, lightdiff);
                }

                if (bestTarget == null || curTarget.W > bestTarget.W)
                {
                    bestTarget = new Vec4d(curTarget.X, curTarget.Y, curTarget.Z, curTarget.W);
                }
            }


            if (bestTarget.W > 0)
            {
                //double bla = bestTarget.Y;
                //bestTarget.Y += 1;
                //dx = bestTarget.X - entity.ServerPos.X;
                //dz = bestTarget.Z - entity.ServerPos.Z;
                //Vec3d sadf = bestTarget.XYZ.Ahead(1, 0, (float)Math.Atan2(dx, dz) + GameMath.PIHALF);

                /*(entity.Api as ICoreServerAPI).World.HighlightBlocks(world.AllOnlinePlayers[0], 10, new List<BlockPos>() {
                 * new BlockPos((int)bestTarget.X, (int)bestTarget.Y, (int)bestTarget.Z) }, new List<int>() { ColorUtil.ColorFromRgba(0, 255, 0, 80) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                 * (entity.Api as ICoreServerAPI).World.HighlightBlocks(world.AllOnlinePlayers[0], 11, new List<BlockPos>() {
                 * new BlockPos((int)sadf.X, (int)sadf.Y, (int)sadf.Z) }, new List<int>() { ColorUtil.ColorFromRgba(0, 255, 255, 180) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);*/

                //bestTarget.Y = bla;


                FailedConsecutivePathfinds = Math.Max(FailedConsecutivePathfinds - 3, 0);
                return(bestTarget.XYZ);
            }

            FailedConsecutivePathfinds++;
            return(null);
        }
Beispiel #14
0
 public static extern ExceptionStatus core_FileNode_read_Vec4d(IntPtr node, out Vec4d returnValue);
Beispiel #15
0
        public Vec3d loadNextWanderTarget()
        {
            int      tries      = 9;
            Vec4d    bestTarget = null;
            Vec4d    curTarget  = new Vec4d();
            BlockPos tmpPos     = new BlockPos();

            if (FailedConsecutivePathfinds > 10)
            {
                WanderRangeMul = Math.Max(0.1f, WanderRangeMul * 0.9f);
            }
            else
            {
                WanderRangeMul = Math.Min(1, WanderRangeMul * 1.1f);
                if (rand.NextDouble() < 0.05)
                {
                    WanderRangeMul = Math.Min(1, WanderRangeMul * 1.5f);
                }
            }

            float  wRangeMul = WanderRangeMul;
            double dx, dy, dz;

            if (rand.NextDouble() < 0.05)
            {
                wRangeMul *= 3;
            }

            while (tries-- > 0)
            {
                dx = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dy = wanderRangeVertical.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dz = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;

                curTarget.X = entity.ServerPos.X + dx;
                curTarget.Y = entity.ServerPos.Y + dy;
                curTarget.Z = entity.ServerPos.Z + dz;
                curTarget.W = 1;

                Block block;

                block = entity.World.BlockAccessor.GetBlock((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                if (!block.IsLiquid())
                {
                    curTarget.W = 0;
                }
                else
                {
                    curTarget.W = 1 / (Math.Abs(dy) + 1);   //prefer not too much vertical change when underwater
                }
                //TODO: reject (or de-weight) targets not in direct line of sight (avoiding terrain)


                if (preferredLightLevel != null && curTarget.W != 0)
                {
                    tmpPos.Set((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                    int lightdiff = Math.Abs((int)preferredLightLevel - entity.World.BlockAccessor.GetLightLevel(tmpPos, EnumLightLevelType.MaxLight));

                    curTarget.W /= Math.Max(1, lightdiff);
                }

                if (bestTarget == null || curTarget.W > bestTarget.W)
                {
                    bestTarget = new Vec4d(curTarget.X, curTarget.Y, curTarget.Z, curTarget.W);
                    if (curTarget.W >= 1.0)
                    {
                        break;                      //have a good enough target, no need for further tries
                    }
                }
            }


            if (bestTarget.W > 0)
            {
                FailedConsecutivePathfinds = Math.Max(FailedConsecutivePathfinds - 3, 0);
                return(bestTarget.XYZ);
            }

            FailedConsecutivePathfinds++;
            return(null);
        }
Beispiel #16
0
 public static extern ExceptionStatus core_FileStorage_shift_Vec4d(IntPtr fs, Vec4d val);
        private Vec3d nearbyWaterOrRandomTarget()
        {
            int      tries      = 9;
            Vec4d    bestTarget = null;
            Vec4d    curTarget  = new Vec4d();
            BlockPos tmpPos     = new BlockPos();

            if (FailedConsecutivePathfinds > 10)
            {
                WanderRangeMul = Math.Max(0.1f, WanderRangeMul * 0.9f);
            }
            else
            {
                WanderRangeMul = Math.Min(1, WanderRangeMul * 1.1f);
                if (rand.NextDouble() < 0.05)
                {
                    WanderRangeMul = Math.Min(1, WanderRangeMul * 1.5f);
                }
            }

            float  wRangeMul = WanderRangeMul;
            double dx, dy, dz;

            if (rand.NextDouble() < 0.05)
            {
                wRangeMul *= 3;
            }

            while (tries-- > 0)
            {
                dx = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dy = wanderRangeVertical.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;
                dz = wanderRangeHorizontal.nextFloat() * (rand.Next(2) * 2 - 1) * wRangeMul;

                curTarget.X = entity.ServerPos.X + dx;
                curTarget.Y = entity.ServerPos.Y + dy;
                curTarget.Z = entity.ServerPos.Z + dz;
                curTarget.W = 1;

                Block block;

                block = entity.World.BlockAccessor.GetBlock((int)curTarget.X, (int)curTarget.Y, (int)curTarget.Z);
                if (!block.IsLiquid())
                {
                    curTarget.W = 0;
                }
                else
                {
                    curTarget.W = 1 / Math.Sqrt((dx - 1.0) * (dx - 1.0) + (dz - 1.0) * (dz - 1.0) + 1);   //prefer target approx 1 block away
                }
                //TODO: reject (or de-weight) targets not in direct line of sight (avoiding terrain)


                if (bestTarget == null || curTarget.W > bestTarget.W)
                {
                    bestTarget = new Vec4d(curTarget.X, curTarget.Y, curTarget.Z, curTarget.W);
                    if (curTarget.W >= 1.0)
                    {
                        break;                      //have a good enough target, no need for further tries
                    }
                }
            }


            if (bestTarget.W > 0)
            {
                FailedConsecutivePathfinds = Math.Max(FailedConsecutivePathfinds - 3, 0);
                return(bestTarget.XYZ);
            }

            FailedConsecutivePathfinds++;
            return(null);
        }
Beispiel #18
0
        public static void ConvertAnimation(string refpose, string input, string output)
        {
            NumberFormatInfo format = new NumberFormatInfo();

            format.NumberDecimalSeparator = ".";
            StreamReader          refpose_reader    = new StreamReader(refpose);
            int                   refpose_bonecount = Convert.ToInt32(refpose_reader.ReadLine());
            Dictionary <int, int> refpose_parentmap = new Dictionary <int, int>();
            Dictionary <int, int> refpose_indexmap  = new Dictionary <int, int>();

            int[] refpose_bonearray = new int[refpose_bonecount];
            int[] refpose_hierarchy = new int[refpose_bonecount];
            refpose_reader.ReadLine();
            refpose_reader.ReadLine();
            for (int index = 0; index < refpose_bonecount; ++index)
            {
                string[] array = refpose_reader.ReadLine().Replace("\"", string.Empty).Split(' ');
                refpose_bonearray[index] = Convert.ToInt32(array[1].Split('_').Last(), 16);
                refpose_hierarchy[index] = Convert.ToInt32(array[2]);
            }

            for (int index = 0; index < refpose_bonecount; ++index)
            {
                if (refpose_hierarchy[index] != -1)
                {
                    refpose_parentmap.Add(refpose_bonearray[index], refpose_bonearray[refpose_hierarchy[index]]);
                }
                else
                {
                    refpose_parentmap.Add(refpose_bonearray[index], -1);
                }
                refpose_indexmap.Add(refpose_bonearray[index], index);
            }
            refpose_reader.ReadLine();
            refpose_reader.ReadLine();
            refpose_reader.ReadLine();
            Vector3D[] refpose_position = new Vector3D[refpose_bonecount];
            Vector3D[] refpose_rotation = new Vector3D[refpose_bonecount];
            Vector3D[] refpose_scale    = new Vector3D[refpose_bonecount];
            for (int index = 0; index < refpose_bonecount; ++index)
            {
                refpose_position[index] = new Vector3D();
                refpose_rotation[index] = new Vector3D();
                refpose_scale[index]    = new Vector3D(1, 1, 1);
                string[] array = refpose_reader.ReadLine().Replace("\"", string.Empty).Split(' ');
                refpose_position[index].X = Convert.ToSingle(array[2], format);
                refpose_position[index].Y = Convert.ToSingle(array[3], format);
                refpose_position[index].Z = Convert.ToSingle(array[4], format);
                refpose_rotation[index].X = Convert.ToSingle(array[6], format);
                refpose_rotation[index].Y = Convert.ToSingle(array[7], format);
                refpose_rotation[index].Z = Convert.ToSingle(array[8], format);
            }
            refpose_reader.Close();
            FileStream   inputStream  = new FileStream(input, FileMode.Open);
            BinaryReader input_reader = new BinaryReader(inputStream);

            input_reader.ReadInt32();
            float  duration   = input_reader.ReadSingle();
            float  fps        = input_reader.ReadSingle();
            ushort bone_count = input_reader.ReadUInt16();

            input_reader.ReadUInt16();
            int frame_count = (int)(fps * (double)duration) + 1;

            inputStream.Seek(24L, SeekOrigin.Current);
            long offset_bone_list  = input_reader.ReadInt64();
            long offset_info_table = input_reader.ReadInt64();

            inputStream.Seek(24L, SeekOrigin.Current);
            StreamWriter output_writer = new StreamWriter(output);

            output_writer.WriteLine("version 1");
            output_writer.WriteLine("nodes");
            int[] bone_list = new int[bone_count];
            inputStream.Seek(offset_bone_list, SeekOrigin.Begin);
            Dictionary <int, int> bone_translation_map = new Dictionary <int, int>();
            int bone_id;

            for (int index = 0; index < bone_count; ++index)
            {
                bone_id          = input_reader.ReadInt32();
                bone_list[index] = bone_id;
                bone_translation_map.Add(bone_id, index);
            }
            for (int index = 0; index < bone_count; ++index)
            {
                bone_id = bone_list[index];
                int num3 = -1;
                if (refpose_parentmap.ContainsKey(bone_id))
                {
                    int key2 = refpose_parentmap[bone_id];
                    num3 = !bone_translation_map.ContainsKey(key2) ? -1 : bone_translation_map[key2];
                }
                output_writer.WriteLine(index.ToString() + " \"bone_" + bone_id.ToString("X4") + "\" " + num3);
            }
            int last_bone_index = bone_count;
            Dictionary <int, int> secondary_bone_translation_map = new Dictionary <int, int>();

            for (int index = 0; index < refpose_bonecount; ++index)
            {
                if (!bone_translation_map.ContainsKey(refpose_bonearray[index]))
                {
                    secondary_bone_translation_map.Add(refpose_bonearray[index], last_bone_index);
                }
            }

            for (int index = 0; index < refpose_bonecount; ++index)
            {
                if (!bone_translation_map.ContainsKey(refpose_bonearray[index]))
                {
                    int key2 = refpose_parentmap[refpose_bonearray[index]];
                    int num3 = !bone_translation_map.ContainsKey(key2) ? (!secondary_bone_translation_map.ContainsKey(key2) ? -1 : secondary_bone_translation_map[key2]) : bone_translation_map[key2];
                    output_writer.WriteLine(last_bone_index.ToString() + " \"bone_" + refpose_bonearray[index].ToString("X4") + "\" " + num3);
                    ++last_bone_index;
                }
            }
            output_writer.WriteLine("end");
            float[,] x_array           = new float[last_bone_index, frame_count];
            float[,] y_array           = new float[last_bone_index, frame_count];
            float[,] z_array           = new float[last_bone_index, frame_count];
            float[,] sx_array          = new float[last_bone_index, frame_count];
            float[,] sy_array          = new float[last_bone_index, frame_count];
            float[,] sz_array          = new float[last_bone_index, frame_count];
            float[,] rx_array          = new float[last_bone_index, frame_count];
            float[,] ry_array          = new float[last_bone_index, frame_count];
            float[,] rz_array          = new float[last_bone_index, frame_count];
            float[,] rw_array          = new float[last_bone_index, frame_count];
            bool[,] has_rotation_frame = new bool[last_bone_index, frame_count];
            bool[,] has_position_frame = new bool[last_bone_index, frame_count];
            bool[,] has_scale_frame    = new bool[last_bone_index, frame_count];
            output_writer.WriteLine("skeleton");
            output_writer.WriteLine("time 0");
            for (int index = 0; index < bone_count; ++index)
            {
                if (refpose_indexmap.ContainsKey(bone_list[index]))
                {
                    bone_id = refpose_indexmap[bone_list[index]];
                    output_writer.Write(index);
                    output_writer.Write(" " + refpose_position[bone_id].X.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_position[bone_id].Y.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_position[bone_id].Z.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[bone_id].X.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[bone_id].Y.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[bone_id].Z.ToString("0.000000", format));
                    output_writer.WriteLine();
                }
                else
                {
                    output_writer.WriteLine(index.ToString() + " 0 0 0 0 0 0");
                }
            }
            int num4 = bone_count;

            for (int index = 0; index < refpose_bonecount; ++index)
            {
                if (!bone_translation_map.ContainsKey(refpose_bonearray[index]))
                {
                    output_writer.Write(num4++);
                    output_writer.Write(" " + refpose_position[index].X.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_position[index].Y.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_position[index].Z.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[index].X.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[index].Y.ToString("0.000000", format));
                    output_writer.Write(" " + refpose_rotation[index].Z.ToString("0.000000", format));
                    output_writer.WriteLine();
                }
            }
            Quaternion3D q        = new Quaternion3D();
            Vector3D     vector3D = new Vector3D();

            inputStream.Seek(offset_info_table, SeekOrigin.Begin);
            for (int index1 = 0; index1 < bone_count; ++index1)
            {
                long  position                = inputStream.Position;
                int   scale_count             = input_reader.ReadInt16();
                int   position_count          = input_reader.ReadInt16();
                int   rotation_count          = input_reader.ReadInt16();
                int   flags                   = input_reader.ReadInt16();
                long  scale_indices_offset    = input_reader.ReadInt32() * 4 + position;
                long  position_indices_offset = input_reader.ReadInt32() * 4 + position;
                long  rotation_indices_offset = input_reader.ReadInt32() * 4 + position;
                long  scale_data_offset       = input_reader.ReadInt32() * 4 + position;
                long  position_data_offset    = input_reader.ReadInt32() * 4 + position;
                long  rotation_data_offset    = input_reader.ReadInt32() * 4 + position;
                int[] scale_indices           = new int[scale_count];
                inputStream.Seek(scale_indices_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < scale_count; ++index2)
                {
                    scale_indices[index2] = frame_count > byte.MaxValue ? input_reader.ReadInt16() : input_reader.ReadByte();
                }
                inputStream.Seek(scale_data_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < scale_count; ++index2)
                {
                    int index3 = scale_indices[index2];
                    has_scale_frame[index1, index3] = true;
                    float x = input_reader.ReadUInt16() / 1024.0f;
                    sx_array[index1, index3] = x;
                    float y = input_reader.ReadUInt16() / 1024.0f;
                    sy_array[index1, index3] = y;
                    float z = input_reader.ReadUInt16() / 1024.0f;
                    sz_array[index1, index3] = z;
                }
                int[] position_indices = new int[position_count];
                inputStream.Seek(position_indices_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < position_count; ++index2)
                {
                    position_indices[index2] = frame_count > byte.MaxValue ? input_reader.ReadInt16() : input_reader.ReadByte();
                }
                inputStream.Seek(position_data_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < position_count; ++index2)
                {
                    int index3 = position_indices[index2];
                    has_position_frame[index1, index3] = true;
                    float x = input_reader.ReadSingle();
                    x_array[index1, index3] = x;
                    float y = input_reader.ReadSingle();
                    y_array[index1, index3] = y;
                    float z = input_reader.ReadSingle();
                    z_array[index1, index3] = z;
                }
                int[] rotation_indices = new int[rotation_count];
                inputStream.Seek(rotation_indices_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < rotation_count; ++index2)
                {
                    rotation_indices[index2] = frame_count > byte.MaxValue ? input_reader.ReadInt16() : input_reader.ReadByte();
                }
                inputStream.Seek(rotation_data_offset, SeekOrigin.Begin);
                for (int index2 = 0; index2 < rotation_count; ++index2)
                {
                    ushort rot_a  = input_reader.ReadUInt16();
                    ushort rot_b  = input_reader.ReadUInt16();
                    ushort rot_c  = input_reader.ReadUInt16();
                    Vec4d  rot    = Animation.UnpackRotation(rot_a, rot_b, rot_c);
                    int    index3 = rotation_indices[index2];
                    has_rotation_frame[index1, index3] = true;
                    rx_array[index1, index3]           = (float)rot.x;
                    ry_array[index1, index3]           = (float)rot.y;
                    rz_array[index1, index3]           = (float)rot.z;
                    rw_array[index1, index3]           = (float)rot.w;
                }
                inputStream.Seek(position + 32L, SeekOrigin.Begin);
            }
            for (int index1 = 0; index1 < frame_count; ++index1)
            {
                output_writer.WriteLine($"time {index1 + 1}");
                for (int index2 = 0; index2 < last_bone_index; ++index2)
                {
                    if (has_position_frame[index2, index1] || has_rotation_frame[index2, index1] || has_scale_frame[index2, index1])
                    {
                        if (!has_position_frame[index2, index1])
                        {
                            int index3 = index1;
                            int index4 = index1;
                            while (!has_position_frame[index2, index3])
                            {
                                --index3;
                            }
                            while (index4 < frame_count && !has_position_frame[index2, index4])
                            {
                                ++index4;
                            }
                            if (index4 == frame_count)
                            {
                                x_array[index2, index1] = x_array[index2, index3];
                                y_array[index2, index1] = y_array[index2, index3];
                                z_array[index2, index1] = z_array[index2, index3];
                            }
                            else
                            {
                                float num3 = (index1 - index3) / (float)(index4 - index3);
                                x_array[index2, index1] = (x_array[index2, index4] - x_array[index2, index3]) * num3 + x_array[index2, index3];
                                y_array[index2, index1] = (y_array[index2, index4] - y_array[index2, index3]) * num3 + y_array[index2, index3];
                                z_array[index2, index1] = (z_array[index2, index4] - z_array[index2, index3]) * num3 + z_array[index2, index3];
                            }
                        }
                        if (!has_scale_frame[index2, index1])
                        {
                            int index3 = index1;
                            int index4 = index1;
                            while (!has_scale_frame[index2, index3])
                            {
                                --index3;
                            }
                            while (index4 < frame_count && !has_scale_frame[index2, index4])
                            {
                                ++index4;
                            }
                            if (index4 == frame_count)
                            {
                                sx_array[index2, index1] = sx_array[index2, index3];
                                sy_array[index2, index1] = sy_array[index2, index3];
                                sz_array[index2, index1] = sz_array[index2, index3];
                            }
                            else
                            {
                                float num3 = (index1 - index3) / (float)(index4 - index3);
                                sx_array[index2, index1] = (sx_array[index2, index4] - sx_array[index2, index3]) * num3 + sx_array[index2, index3];
                                sy_array[index2, index1] = (sy_array[index2, index4] - sy_array[index2, index3]) * num3 + sy_array[index2, index3];
                                sz_array[index2, index1] = (sz_array[index2, index4] - sz_array[index2, index3]) * num3 + sz_array[index2, index3];
                            }
                        }
                        if (!has_rotation_frame[index2, index1])
                        {
                            int index3 = index1;
                            int index4 = index1;
                            while (!has_rotation_frame[index2, index3])
                            {
                                --index3;
                            }
                            while (index4 < frame_count && !has_rotation_frame[index2, index4])
                            {
                                ++index4;
                            }
                            if (index4 == frame_count)
                            {
                                rx_array[index2, index1] = rx_array[index2, index3];
                                ry_array[index2, index1] = ry_array[index2, index3];
                                rz_array[index2, index1] = rz_array[index2, index3];
                                rw_array[index2, index1] = rw_array[index2, index3];
                            }
                            else
                            {
                                double num3 = rx_array[index2, index4] * (double)rx_array[index2, index3] + ry_array[index2, index4] * (double)ry_array[index2, index3] + rz_array[index2, index4] * (double)rz_array[index2, index3] + rw_array[index2, index4] * (double)rw_array[index2, index3];
                                float  num9 = (index1 - index3) / (float)(index4 - index3);
                                if (num3 < 0.0)
                                {
                                    rx_array[index2, index1] = (-rx_array[index2, index4] - rx_array[index2, index3]) * num9 + rx_array[index2, index3];
                                    ry_array[index2, index1] = (-ry_array[index2, index4] - ry_array[index2, index3]) * num9 + ry_array[index2, index3];
                                    rz_array[index2, index1] = (-rz_array[index2, index4] - rz_array[index2, index3]) * num9 + rz_array[index2, index3];
                                    rw_array[index2, index1] = (-rw_array[index2, index4] - rw_array[index2, index3]) * num9 + rw_array[index2, index3];
                                }
                                else
                                {
                                    rx_array[index2, index1] = (rx_array[index2, index4] - rx_array[index2, index3]) * num9 + rx_array[index2, index3];
                                    ry_array[index2, index1] = (ry_array[index2, index4] - ry_array[index2, index3]) * num9 + ry_array[index2, index3];
                                    rz_array[index2, index1] = (rz_array[index2, index4] - rz_array[index2, index3]) * num9 + rz_array[index2, index3];
                                    rw_array[index2, index1] = (rw_array[index2, index4] - rw_array[index2, index3]) * num9 + rw_array[index2, index3];
                                }
                            }
                        }
                        output_writer.Write(index2);
                        output_writer.Write(" " + x_array[index2, index1].ToString("0.000000", format));
                        output_writer.Write(" " + y_array[index2, index1].ToString("0.000000", format));
                        output_writer.Write(" " + z_array[index2, index1].ToString("0.000000", format));
                        q.i    = rx_array[index2, index1];
                        q.j    = ry_array[index2, index1];
                        q.k    = rz_array[index2, index1];
                        q.real = rw_array[index2, index1];
                        Vector3D eulerAngles = C3D.ToEulerAngles(q);
                        output_writer.Write(" " + eulerAngles.X.ToString("0.000000", format));
                        output_writer.Write(" " + eulerAngles.Y.ToString("0.000000", format));
                        output_writer.Write(" " + eulerAngles.Z.ToString("0.000000", format));
                        output_writer.WriteLine();
                    }
                }
            }
            output_writer.WriteLine("end");
            output_writer.Close();
        }