예제 #1
0
        public void RotateComponent()
        {
            var d1 = SpaceEngineersApi.GetCubeDefinition(new MyObjectBuilderType(typeof(MyObjectBuilder_Thrust)), MyCubeSize.Large, "LargeBlockLargeThrust");

            Assert.AreEqual("DisplayName_Block_LargeThrust", d1.DisplayNameEnum.Value.String, "Must match");
            Assert.AreEqual(MyCubeSize.Large, d1.CubeSize, "Must match");

            Assert.AreEqual(3, d1.Size.X, "Must match");
            Assert.AreEqual(2, d1.Size.Y, "Must match");
            Assert.AreEqual(4, d1.Size.Z, "Must match");

            //======//

            var orient = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);

            var f = Base6Directions.GetVector(orient.Forward);
            var u = Base6Directions.GetVector(orient.Up);

            var m = Matrix.CreateFromDir(f, u);
            var q = Quaternion.CreateFromRotationMatrix(m);

            var nf = Base6Directions.GetForward(q);
            var nu = Base6Directions.GetUp(q);

            // Test that Space Engineers orientation methods are working as expected. Forward is still Forward, Up is still Up.
            Assert.AreEqual(nf, orient.Forward, "Initial Orientation Forward must match.");
            Assert.AreEqual(nu, orient.Up, "Initial Orientation Forward must match.");

            //======//

            var v   = d1.Size;
            var fV1 = Vector3.Transform(v, m);

            // Orientation of Forward/Up should provide the exact same dimentions as the original Component above.
            Assert.AreEqual(3, fV1.X, "Must match");
            Assert.AreEqual(2, fV1.Y, "Must match");
            Assert.AreEqual(4, fV1.Z, "Must match");

            //======//

            var newOrient = new SerializableBlockOrientation(Base6Directions.Direction.Down, Base6Directions.Direction.Right);

            var newM = Matrix.CreateFromDir(Base6Directions.GetVector(newOrient.Forward), Base6Directions.GetVector(newOrient.Up));

            var fV2 = Vector3.Transform(v, newM);

            // The reoriented Component size should now have changed.
            Assert.AreEqual(2, fV2.X, "Must match");
            Assert.AreEqual(4, fV2.Y, "Must match");
            Assert.AreEqual(3, fV2.Z, "Must match");

            //======//

            // Reducing complexity of code with Extension.
            var direction = new SerializableBlockOrientation(Base6Directions.Direction.Down, Base6Directions.Direction.Right);
            var fV3       = d1.Size.Transform(direction);

            // The reoriented Component size should now have changed.
            Assert.AreEqual(2, fV3.X, "Must match");
            Assert.AreEqual(4, fV3.Y, "Must match");
            Assert.AreEqual(3, fV3.Z, "Must match");
        }
 public SerializableBlockOrientation(ref Quaternion q)
 {
     Forward = Base6Directions.GetForward(q);
     Up      = Base6Directions.GetUp(q);
 }
        public void BroadcastAddCubeBlock(CubeBlockEntity cubeBlock)
        {
            try
            {
                Type   packedStructType   = CubeGridEntity.InternalType.GetNestedType(CubeGridEntity.CubeGridPackedCubeBlockClass);
                Object packedStruct       = Activator.CreateInstance(packedStructType);
                MyCubeBlockDefinition def = MyDefinitionManager.Static.GetCubeBlockDefinition(cubeBlock.ObjectBuilder);

                //Set def id
                BaseObject.SetEntityFieldValue(packedStruct, "35E024D9E3B721592FB9B6FC1A1E239A", (DefinitionIdBlit)def.Id);

                //Set position
                BaseObject.SetEntityFieldValue(packedStruct, "5C3938C9B8CED1D0057CCF12F04329AB", cubeBlock.Position);

                //Set block size
                BaseObject.SetEntityFieldValue(packedStruct, "0DDB53EB9299ECC9826DF9A47E5E4F38", new Vector3UByte(def.Size));

                //Set block margins
                BaseObject.SetEntityFieldValue(packedStruct, "4045ED59A8C93DE0B41218EF2E947E55", new Vector3B(0, 0, 0));
                BaseObject.SetEntityFieldValue(packedStruct, "096897446D5BD5243D3D6E5C53CE1772", new Vector3B(0, 0, 0));

                //Set block margin scale
                BaseObject.SetEntityFieldValue(packedStruct, "E28B9725868E18B339D1E0594EF14444", new Vector3B(0, 0, 0));

                //Set orientation
                Quaternion rot;
                cubeBlock.BlockOrientation.GetQuaternion(out rot);
                BaseObject.SetEntityFieldValue(packedStruct, "F1AAFF5C8F200592F313BC7E02140A38", Base6Directions.GetForward(rot));
                BaseObject.SetEntityFieldValue(packedStruct, "E80AA7B84131E39F9F88209A109EED59", Base6Directions.GetUp(rot));

                //Set color
                BaseObject.SetEntityFieldValue(packedStruct, "556976F2528411FF5F95FC75DC13FEED", ColorExtensions.PackHSVToUint(cubeBlock.ColorMaskHSV));

                object[] parameters =
                {
                    packedStruct,
                    new HashSet <Vector3UByte>(),
                    cubeBlock.EntityId,
                    MyRandom.Instance.CreateRandomSeed()
                };
                BaseObject.InvokeEntityMethod(m_netManager, CubeGridNetManagerBroadcastAddCubeBlockMethod, parameters);
            }
            catch (Exception ex)
            {
                LogManager.ErrorLog.WriteLine(ex);
            }
        }
        private static void MirrorCubeOrientation(MyCubeBlockDefinition definition, SerializableBlockOrientation orientation, MirrorDirection xMirror, MirrorDirection yMirror, MirrorDirection zMirror, out MyCubeBlockDefinition mirrorDefinition, out SerializableBlockOrientation mirrorOrientation)
        {
            if (string.IsNullOrEmpty(definition.MirroringBlock))
            {
                mirrorDefinition = definition;
            }
            else
            {
                var definitionId = new MyDefinitionId(definition.Id.TypeId, definition.MirroringBlock);
                mirrorDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(definitionId);
            }

            Matrix sourceMatrix = Matrix.CreateFromDir(Base6Directions.GetVector(orientation.Forward), Base6Directions.GetVector(orientation.Up));
            Matrix targetMatrix;

            Vector3 mirrorNormal = Vector3.Zero;

            if (xMirror != MirrorDirection.None)
            {
                mirrorNormal = Vector3.Right;
            }
            else if (yMirror != MirrorDirection.None)
            {
                mirrorNormal = Vector3.Up;
            }
            else if (zMirror != MirrorDirection.None)
            {
                mirrorNormal = Vector3.Forward;
            }

            MySymmetryAxisEnum blockMirrorAxis = MySymmetryAxisEnum.None;

            if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceMatrix.Right, mirrorNormal)) - 1.0f))
            {
                blockMirrorAxis = MySymmetryAxisEnum.X;
            }
            else if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceMatrix.Up, mirrorNormal)) - 1.0f))
            {
                blockMirrorAxis = MySymmetryAxisEnum.Y;
            }
            else if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceMatrix.Forward, mirrorNormal)) - 1.0f))
            {
                blockMirrorAxis = MySymmetryAxisEnum.Z;
            }

            MySymmetryAxisEnum blockMirrorOption = MySymmetryAxisEnum.None;

            switch (blockMirrorAxis)
            {
            case MySymmetryAxisEnum.X: blockMirrorOption = definition.SymmetryX; break;

            case MySymmetryAxisEnum.Y: blockMirrorOption = definition.SymmetryY; break;

            case MySymmetryAxisEnum.Z: blockMirrorOption = definition.SymmetryZ; break;

            default:
                throw new Exception("Invalid mirror option");
            }

            switch (blockMirrorOption)
            {
            case MySymmetryAxisEnum.X:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.Y:
            case MySymmetryAxisEnum.YThenOffsetX:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.Z:
            case MySymmetryAxisEnum.ZThenOffsetX:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.HalfX:
                targetMatrix = Matrix.CreateRotationX(-MathHelper.PiOver2) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.HalfY:
                targetMatrix = Matrix.CreateRotationY(-MathHelper.PiOver2) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.HalfZ:
                targetMatrix = Matrix.CreateRotationZ(-MathHelper.PiOver2) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.XHalfY:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.YHalfY:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.ZHalfY:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.XHalfX:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.YHalfX:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.ZHalfX:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.XHalfZ:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.YHalfZ:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.ZHalfZ:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.XMinusHalfZ:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.YMinusHalfZ:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.ZMinusHalfZ:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.XMinusHalfX:
                targetMatrix = Matrix.CreateRotationX(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.YMinusHalfX:
                targetMatrix = Matrix.CreateRotationY(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.ZMinusHalfX:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.Pi) * sourceMatrix;
                targetMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * targetMatrix;
                break;

            case MySymmetryAxisEnum.MinusHalfX:
                targetMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.MinusHalfY:
                targetMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * sourceMatrix;
                break;

            case MySymmetryAxisEnum.MinusHalfZ:
                targetMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * sourceMatrix;
                break;

            default:     // or MySymmetryAxisEnum.None
                targetMatrix = sourceMatrix;
                break;
            }

            // Note, the Base6Directions methods call GetDirection(), which rounds off the vector, which should prevent floating point errors creeping in.
            mirrorOrientation = new SerializableBlockOrientation(Base6Directions.GetForward(ref targetMatrix), Base6Directions.GetUp(ref targetMatrix));
        }