【退役生活】SimpleRockets2

NCC79601

2020-01-12 17:09:48

Personal

# Source Code ```cpp #include <bits/stdc++.h> #include <windows.h> using namespace std; const int MAXN = 4e3; struct colorInfo { int R, G, B; } array[MAXN][MAXN]; int N, M; int size, tot = 0; double len, scale; struct bmp { // save the information of bitmap // partly from the Internet unsigned char *pBmpBuf; int bmpWidth; int bmpHeight; RGBQUAD *pColorTable; int biBitCount; // definitions void read(char *filename) { // read the bitmap under binary-read mode FILE *fp = fopen(filename, "rb"); if (fp == NULL) return ; fseek(fp, sizeof(BITMAPFILEHEADER), 0); BITMAPINFOHEADER head; fread(&head, sizeof(BITMAPINFOHEADER), 1, fp); bmpWidth = head.biWidth; bmpHeight = head.biHeight; biBitCount = head.biBitCount; N = bmpHeight, M = bmpWidth; int lineByte = (bmpWidth * biBitCount / 8 + 3) / 4 * 4; if (biBitCount == 8) { pColorTable = new RGBQUAD[256]; fread(pColorTable, sizeof(RGBQUAD), 256, fp); } pBmpBuf = new unsigned char[lineByte * bmpHeight]; fread(pBmpBuf, 1, lineByte * bmpHeight, fp); fclose(fp); return ; } void write(char *filename, unsigned char *imgBuf, int width, int height, int biBitCount, RGBQUAD *pColorTable) { // write the color information into pixel_array.txt // and generate a copy of the bitmap to debug if (!imgBuf) return ; int colorTablesize = 0; if (biBitCount == 8) colorTablesize = 1024; int lineByte = (width * biBitCount / 8 + 3) / 4 * 4; FILE *fp = fopen(filename, "wb"); if (fp == NULL) return ; BITMAPFILEHEADER fileHead; fileHead.bfType = 0x4D42; fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte * height; fileHead.bfReserved1 = 0; fileHead.bfReserved2 = 0; fileHead.bfOffBits = 54 + colorTablesize; fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp); BITMAPINFOHEADER head; head.biBitCount = biBitCount; head.biClrImportant = 0; head.biClrUsed = 0; head.biCompression = 0; head.biHeight = height; head.biPlanes = 1; head.biSize = 40; head.biSizeImage = lineByte * height; head.biWidth = width; head.biXPelsPerMeter = 0; head.biYPelsPerMeter = 0; fwrite(&head, sizeof(BITMAPINFOHEADER), 1, fp); if (biBitCount == 8) fwrite(pColorTable, sizeof(RGBQUAD), 256, fp); fwrite(imgBuf, height * lineByte, 1, fp); fclose(fp); return ; } void convert(char *filename) { // proceed convertion read(filename); printf("[infor] Width: %d, Height: %d, biBitCount: %d.\n", bmpWidth, bmpHeight, biBitCount); int lineByte = (bmpWidth * biBitCount / 8 + 3) / 4 * 4; int m = 0, n = 0, pixleCnt = 0; ofstream outfile("pixel_array.txt", ios::in | ios::trunc); if (biBitCount == 8) { printf("[warning] received non-24-bit bmp. (exit without futher actions)\n"); int l1 = 0, x = 63, y = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { for (l1 = x; l1 > x - 8; l1--) for (int l2 = y; l2 < y + 8; l2++) { m = *(pBmpBuf + l1 * lineByte + l2); outfile << m << " "; pixleCnt++; if (pixleCnt % 3 == 0) outfile << endl; } x = 63 - i * 8, y += 8; } x -= 8, y = 0; } } if (!outfile) { printf("[error] no such file found."); exit(0); } else if (biBitCount == 24) { printf("[infor] received 24-bit bmp. Proceed to convert.\n"); for (int i = 0; i < bmpHeight; i++) for (int j = 0; j < bmpWidth; j++, n++) for (int k = 0; k < 3; k++) { m = *(pBmpBuf + i * lineByte + j * 3 + k); outfile << m << " "; pixleCnt++; switch (pixleCnt % 3) { case 1: { array[i][j].R = m; break; } case 2: { array[i][j].G = m; break; } case 0: { array[i][j].B = m; outfile << endl; break; } } } printf("[infor] total pixel number: %d\n", n); } char outpath[] = "copy.bmp"; write(outpath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); delete[] pBmpBuf; if (biBitCount == 8) delete[] pColorTable; return ; } } pic; inline int val(int src) { return min(int((src + 10) / 51), 4); } // descrete the color struct block { // store the information of blocks double x, y, z; int id, materials; block(double _x, double _y, double _z) { x = _x, y = _y, z = _z; } block() {} } blocks[MAXN][MAXN]; inline void generateBlocks() { // convert the information in array[] to blocks[] #define Rbase 0 #define Gbase 4 #define Bbase 8 #define BLACK 0 for (int i = 0; i < N * 2; i++) for (int j = 0; j < M * 2; j++, tot++) { int I = i / 2, J = j / 2; blocks[i][j] = block(-(0.5 * i + 0.5) * scale, 0, (0.5 * j + 0.5) * scale); switch ((i % 2) + (j % 2)) { case 0: { // R int v = val(array[I][J].R); blocks[i][j].materials = v ? Rbase + v : BLACK; break; } case 1: { // G int v = val(array[I][J].G); blocks[i][j].materials = v ? Gbase + v : BLACK; break; } case 2: { // B int v = val(array[I][J].B); blocks[i][j].materials = v ? Bbase + v : BLACK; break; } } blocks[i][j].id = tot + 2; } return ; } namespace XML { // functions to write the .xml file // all written by myself inline void generateBasicInfo() { printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); printf("<Craft name=\"craft\" parent=\"\" initialBoundsMin=\"-0.8359594,-1.625213,-0.8359594\" initialBoundsMax=\"0.8359594,1.138787,0.8359594\" price=\"503000\" suppressCraftConfigWarnings=\"false\" xmlVersion=\"10\" localCenterOfMass=\"0,0,0\">\n"); printf(" <Assembly>\n"); printf(" <Parts>\n"); printf(" <Part id=\"1\" partType=\"CommandChip1\" position=\"0,0,0\" rotation=\"0,180,0\" rootPart=\"true\" commandPodId=\"1\" materials=\"0,1,2,3,4\">\n"); printf(" <Drag drag=\"1E-5,0.0001,0.0005,0.001,0,2E-5\" area=\"1E-05,0.0001,0.0005,0.001,1E-05,3E-05\" />\n"); printf(" <Config partScale=\"0.15,0.15,0.15\" />\n"); printf(" <CommandPod activationGroupNames=\",,,,,,,Landing Gear,Solar Panels,RCS\" activationGroupStates=\"false,false,false,false,false,false,false,true,false,true\" pidPitch=\"10,0,25\" pidRoll=\"10,0,25\" pilotSeatRotation=\"270,0,0\">\n"); printf(" <Controls />\n"); printf(" </CommandPod>\n"); printf(" </Part>\n"); return ; } inline void generateBlockInfo() { for (int i = 0; i < N * 2; i++) for (int j = 0; j < M * 2; j++) { printf(" <Part id=\"%d\" partType=\"Block1\" position=\"%.5lf,%.5lf,%.5lf\" rotation=\"0,0,0\" name=\"%d-%d\" commandPodId=\"1\" materials=\"%d,1,2,3,4\">\n", blocks[i][j].id, blocks[i][j].x, blocks[i][j].y, blocks[i][j].z, i, j, blocks[i][j].materials); printf(" <Drag drag=\"0,0.002,0.002,0.001,0,0.002\" area=\"0,0.002,0.002,0.001,0,0.002\" />\n"); printf(" <Config partScale=\"%.2lf,%.2lf,%.2lf\" />\n", scale, scale, scale); printf(" </Part>\n"); } return ; } inline void generateConnectionInfo() { printf(" </Parts>\n"); printf(" <Connections>\n"); for (register int i = 2; i < tot; i++) printf(" <Connection partA=\"%d\" partB=\"%d\" attachPointsA=\"1\" attachPointsB=\"0\" />\n", i, i + 1); printf(" </Connections>\n <Collisions />\n"); printf(" <Bodies>\n"); printf(" </Bodies>\n"); printf(" </Assembly>\n"); return ; } inline void generateColorInfo() { printf(" <DesignerSettings themeName=\"Custom\">\n"); printf(" <Theme name=\"Custom\" id=\"3fe97eda-e2cd-4904-b2ab-15971ec8b516\">\n"); printf(" <Material color=\"000000\" m=\"0.1\" s=\"0.08\" />\n"); // BLACK printf(" <Material color=\"000040\" m=\"0.1\" s=\"0.08\" />\n"); // R1 printf(" <Material color=\"000080\" m=\"0.1\" s=\"0.08\" />\n"); // R2 printf(" <Material color=\"0000C0\" m=\"0.1\" s=\"0.08\" />\n"); // R3 printf(" <Material color=\"0000FF\" m=\"0.1\" s=\"0.08\" />\n"); // R4 printf(" <Material color=\"002000\" m=\"0.1\" s=\"0.08\" />\n"); // G1 (half) printf(" <Material color=\"004000\" m=\"0.1\" s=\"0.08\" />\n"); // G2 (half) printf(" <Material color=\"006000\" m=\"0.1\" s=\"0.08\" />\n"); // G3 (half) printf(" <Material color=\"008000\" m=\"0.1\" s=\"0.08\" />\n"); // G4 (half) printf(" <Material color=\"400000\" m=\"0.1\" s=\"0.08\" />\n"); // B1 printf(" <Material color=\"800000\" m=\"0.1\" s=\"0.08\" />\n"); // B2 printf(" <Material color=\"C00000\" m=\"0.1\" s=\"0.08\" />\n"); // B3 printf(" <Material color=\"FF0000\" m=\"0.1\" s=\"0.08\" />\n"); // B4 printf(" <Material color=\"000000\" m=\"0.1\" s=\"0.08\" />\n"); printf(" <Material color=\"FFFFFF\" m=\"0.65\" s=\"0.08\" />\n </Theme>\n </DesignerSettings>\n"); printf(" <Themes>\n"); printf(" <Theme name=\"Custom\" id=\"78867b5d-f4ed-42a8-9566-6eef32bca546\">\n"); printf(" <Material color=\"000000\" m=\"0.1\" s=\"0.08\" />\n"); // BLACK printf(" <Material color=\"000040\" m=\"0.1\" s=\"0.08\" />\n"); // R1 printf(" <Material color=\"000080\" m=\"0.1\" s=\"0.08\" />\n"); // R2 printf(" <Material color=\"0000C0\" m=\"0.1\" s=\"0.08\" />\n"); // R3 printf(" <Material color=\"0000FF\" m=\"0.1\" s=\"0.08\" />\n"); // R4 printf(" <Material color=\"002C00\" m=\"0.1\" s=\"0.08\" />\n"); // G1 (half) printf(" <Material color=\"005800\" m=\"0.1\" s=\"0.08\" />\n"); // G2 (half) printf(" <Material color=\"008400\" m=\"0.1\" s=\"0.08\" />\n"); // G3 (half) printf(" <Material color=\"00B000\" m=\"0.1\" s=\"0.08\" />\n"); // G4 (half) printf(" <Material color=\"400000\" m=\"0.1\" s=\"0.08\" />\n"); // B1 printf(" <Material color=\"800000\" m=\"0.1\" s=\"0.08\" />\n"); // B2 printf(" <Material color=\"C00000\" m=\"0.1\" s=\"0.08\" />\n"); // B3 printf(" <Material color=\"FF0000\" m=\"0.1\" s=\"0.08\" />\n"); // B4 printf(" <Material color=\"000000\" m=\"0.1\" s=\"0.08\" />\n"); printf(" <Material color=\"FFFFFF\" m=\"0.65\" s=\"0.08\" />\n"); printf(" </Theme>\n </Themes>\n <Symmetry />\n</Craft>\n"); // white balance is corrected return ; } }; int main() { // main function printf("Maximum size supported: 2000 * 2000.\n"); printf("Please enter the filename ($filename$.bmp):\n > "); char filename[1000]; scanf("%s", filename); pic.convert(filename); printf("Please enter the size of your picture in SimpleRockets2 (between 1 and 100):\n > "); scanf("%d", &size); scale = 1.0 * size / 100; len = scale * 0.5; generateBlocks(); freopen("craft.xml", "w", stdout); XML::generateBasicInfo(); XML::generateBlockInfo(); XML::generateConnectionInfo(); XML::generateColorInfo(); cerr << "[infor] generated successfully.\n"; fclose(stdout); return 0; } ``` # Usage ## Step 1 Get a picture (**requirement: 24-bit `.bmp` file.** Personally, I **DO NOT** recommend resolutions larger than 100 * 100, unless you have a really powerful processor) which you want to convert. Copy the source code above and save it in a `.cpp` file. ## Step 2 Put the picture and the cpp file in the same folder. Use `Dev-Cpp` to compile the code (I did not test the code using other compilers). Run the `.exe` file. Follow the instructions and you'll get a `.xml` file in the same directory. ## Step 3 Put the `.xml` file in your craft data folder (generally at `C:\Users\Username\AppData\LocalLow\Jundroo\SimpleRockets 2\UserData\CraftDesigns)`. ## All Done!