Пример #1
0
        public BlockJsonInfo[] Blueprint(string name, BlockJsonInfo root)
        {
            if (botprints == null)
            {
                botprints = BlueprintUtility.ParseBlueprintResource("Pixi.blueprints.json");
            }

            if (!botprints.ContainsKey(root.name) || RobotInternetImporter.CubeSize != 3)
            {
                BlockJsonInfo copy = root;
                copy.name = $"TextBlock\t{root.name} ({CubeUtility.CubeIdDescription(uint.Parse(root.name))})\tPixi";
                return(new BlockJsonInfo[1] {
                    copy
                });
            }
            BlockJsonInfo[] blueprint         = botprints[root.name];
            BlockJsonInfo[] adjustedBlueprint = new BlockJsonInfo[blueprint.Length];
            Quaternion      cubeQuaternion    = Quaternion.Euler(ConversionUtility.FloatArrayToFloat3(root.rotation));

            if (blueprint.Length == 0)
            {
                Logging.LogWarning($"Found empty blueprint for {root.name} (during '{name}'), is the blueprint correct?");
                return(new BlockJsonInfo[0]);
            }
            // move blocks to correct position & rotation
            float3 defaultCorrectionVec = new float3((float)(0), (float)(CommandRoot.BLOCK_SIZE), (float)(0));
            float3 baseRot   = new float3(blueprint[0].rotation[0], blueprint[0].rotation[1], blueprint[0].rotation[2]);
            float3 baseScale = new float3(blueprint[0].scale[0], blueprint[0].scale[1], blueprint[0].scale[2]);
            //Block[] placedBlocks = new Block[blueprint.Length];
            bool   isBaseScaled  = !(blueprint[0].scale[1] > 0f && blueprint[0].scale[1] < 2f);
            float3 correctionVec = isBaseScaled ? (float3)(Quaternion.Euler(baseRot) * baseScale / 2) * (float)-CommandRoot.BLOCK_SIZE : -defaultCorrectionVec;

            // FIXME scaled base blocks cause the blueprint to be placed in the wrong location (this also could be caused by a bug in DumpVON command)
            if (isBaseScaled)
            {
                Logging.LogWarning($"Found blueprint with scaled base block for {root.name} (during '{name}'), this is not currently supported");
            }

            float3 rootPos = ConversionUtility.FloatArrayToFloat3(root.position);

            for (int i = 0; i < blueprint.Length; i++)
            {
                BlockColor blueprintBlockColor = ColorSpaceUtility.QuantizeToBlockColor(blueprint[i].color);
                float[]    physicalColor       = blueprintBlockColor.Color == BlockColors.White && blueprintBlockColor.Darkness == 0 ? root.color : blueprint[i].color;
                float3     bluePos             = ConversionUtility.FloatArrayToFloat3(blueprint[i].position);
                float3     blueScale           = ConversionUtility.FloatArrayToFloat3(blueprint[i].scale);
                float3     blueRot             = ConversionUtility.FloatArrayToFloat3(blueprint[i].rotation);
                float3     physicalLocation    = (float3)(cubeQuaternion * bluePos) + rootPos;         // + (blueprintSizeRotated / 2);
                //physicalLocation.x += blueprintSize.x / 2;
                physicalLocation += (float3)(cubeQuaternion * (correctionVec));
                //physicalLocation.y -= (float)(RobotCommands.blockSize * scale / 2);
                //float3 physicalScale = (float3)(cubeQuaternion * blueScale); // this actually over-rotates when combined with rotation
                float3 physicalScale    = blueScale;
                float3 physicalRotation = (cubeQuaternion * Quaternion.Euler(blueRot)).eulerAngles;
#if DEBUG
                Logging.MetaLog($"Placing blueprint block at {physicalLocation} rot{physicalRotation} scale{physicalScale}");
                Logging.MetaLog($"Location math check original:{bluePos} rotated: {(float3)(cubeQuaternion * bluePos)} actualPos: {rootPos} result: {physicalLocation}");
                Logging.MetaLog($"Scale math check original:{blueScale} rotation: {(float3)cubeQuaternion.eulerAngles} result: {physicalScale}");
                Logging.MetaLog($"Rotation math check original:{blueRot} rotated: {(cubeQuaternion * Quaternion.Euler(blueRot))} result: {physicalRotation}");
#endif
                adjustedBlueprint[i] = new BlockJsonInfo
                {
                    color    = physicalColor,
                    name     = blueprint[i].name,
                    position = ConversionUtility.Float3ToFloatArray(physicalLocation),
                    rotation = ConversionUtility.Float3ToFloatArray(physicalRotation),
                    scale    = ConversionUtility.Float3ToFloatArray(physicalScale)
                };
            }
            return(adjustedBlueprint);
        }
Пример #2
0
        public BlockJsonInfo[] Import(string name)
        {
            // download robot data
            RobotStruct robot;

            try
            {
                RobotBriefStruct[] botList = RoboAPIUtility.ListRobots(name);
                if (botList.Length == 0)
                {
                    throw new Exception("Failed to find robot");
                }
                robot = RoboAPIUtility.QueryRobotInfo(botList[0].itemId);
            }
            catch (Exception e)
            {
                Logging.CommandLogError($"Failed to download robot data. Reason: {e.Message}");
                Logging.MetaLog(e);
                return(new BlockJsonInfo[0]);
            }
            CubeInfo[] cubes = CubeUtility.ParseCubes(robot);
            // move bot closer to origin (since bots are rarely built at the garage bay origin of the bottom south-west corner)
            if (cubes.Length == 0)
            {
                Logging.CommandLogError($"Robot data contains no cubes");
                return(new BlockJsonInfo[0]);
            }
            float3 minPosition = cubes[0].position;

            for (int c = 0; c < cubes.Length; c++)
            {
                float3 cubePos = cubes[c].position;
                if (cubePos.x < minPosition.x)
                {
                    minPosition.x = cubePos.x;
                }
                if (cubePos.y < minPosition.y)
                {
                    minPosition.y = cubePos.y;
                }
                if (cubePos.z < minPosition.z)
                {
                    minPosition.z = cubePos.z;
                }
            }
            BlockJsonInfo[] blocks = new BlockJsonInfo[cubes.Length];
            for (int c = 0; c < cubes.Length; c++)
            {
                ref CubeInfo cube         = ref cubes[c];
                float3       realPosition = ((cube.position - minPosition) * CommandRoot.BLOCK_SIZE * CubeSize);
                if (cube.block == BlockIDs.TextBlock && !string.IsNullOrEmpty(cube.name))
                {
                    // TextBlock block ID means it's a placeholder
                    blocks[c] = new BlockJsonInfo
                    {
                        color    = ColorSpaceUtility.UnquantizeToArray(cube.color, cube.darkness),
                        name     = cube.cubeId.ToString(),
                        position = ConversionUtility.Float3ToFloatArray(realPosition),
                        rotation = ConversionUtility.Float3ToFloatArray(cube.rotation),
                        scale    = ConversionUtility.Float3ToFloatArray(cube.scale)
                    };
                }
                else
                {
                    blocks[c] = new BlockJsonInfo
                    {
                        color    = ColorSpaceUtility.UnquantizeToArray(cube.color, cube.darkness),
                        name     = cube.block.ToString(),
                        position = ConversionUtility.Float3ToFloatArray(realPosition),
                        rotation = ConversionUtility.Float3ToFloatArray(cube.rotation),
                        scale    = ConversionUtility.Float3ToFloatArray(cube.scale * CubeSize)
                    };
                }
            }