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