Skip to content

Instantly share code, notes, and snippets.

@notanimposter
Created February 13, 2016 22:27
Show Gist options
  • Save notanimposter/8c5fabf5ae21527f5c84 to your computer and use it in GitHub Desktop.
Save notanimposter/8c5fabf5ae21527f5c84 to your computer and use it in GitHub Desktop.
3D rendering in Space Engineers (depends on drawlib.cs)
public class CubeViewer {
private static int[][] cubeSides = new int[][] {
SEFix.arr(
1, 1,-1,
1, 1, 1,
-1, 1, 1,
-1, 1,-1
), SEFix.arr(
-1, 1,-1,
-1, 1, 1,
-1,-1, 1,
-1,-1,-1
), SEFix.arr(
1,-1, 1,
1,-1,-1,
-1,-1,-1,
-1,-1, 1
), SEFix.arr(
1,-1, 1,
1, 1, 1,
1, 1,-1,
1,-1,-1
),
SEFix.arr(
1,-1, 1,
1, 1, 1,
-1, 1, 1,
-1,-1, 1
),
SEFix.arr(
1,-1,-1,
1, 1,-1,
-1, 1,-1,
-1,-1,-1
)
};
private static int[][] colors = new int[][] {
SEFix.arr(60,60,60),
SEFix.arr(150,150,150),
SEFix.arr(190,190,190),
SEFix.arr(150,150,150),
SEFix.arr(40,40,40),
SEFix.arr(255,255,255)
};
private int scale;
private double angle1_ = 0;
private double angle2_;
private double cosA = 1;
private double sinA = 0;
private double cosB;
private double sinB;
private double angle1 {
get { return angle1_; }
set {
angle1_ = value + Math.Ceiling( -value / (2*Math.PI)) * 2 *Math.PI;
cosA = Math.Cos(value);
sinA = Math.Sin(value);
}
}
private double angle2 {
get { return angle2_; }
set {
angle2_ = value + Math.Ceiling( -value / (2*Math.PI)) * 2 *Math.PI;
cosB = Math.Cos(value);
sinB = Math.Sin(value);
}
}
private int[][] sides = new int[][] {new int[12], new int[12], new int[12]};
public CubeViewer(double b) {
angle2 = b;
}
private void rotZY(ref double x1, ref double y1, ref double z1) {
double x = x1, y = y1, z = z1;
x1 = x*cosA+y*sinA;
y1 = cosB*(y*cosA-x*sinA)+z*sinB;
z1 = z*cosB-(y*cosA-x*sinA)*sinB;
}
private void pickSides() {
double direction = angle1 / Math.PI * 2;
sides[0] = cubeSides[(int)direction%4];
sides[1] = cubeSides[((int)direction+1)%4];
sides[2] = cubeSides[4+(int)(angle2/Math.PI)];
}
private void cube3d(int x, int y, int z, int[][] polys) {
for (int i=0; i < 3; i++) {
for (int c=0; c<10; c+=3) {
double x1 = x+sides[i][c]*0.5,y1=y+sides[i][c+1]*0.5,z1=z+sides[i][c+2]*0.5;
rotZY(ref x1, ref y1, ref z1);
polys[i][8] = (int)(((c == 0 ? y1*100 : polys[i][8]) + y1*100)/2);
polys[i][9] = Array.IndexOf(cubeSides, sides[i]);
polys[i][c/3*2] = (int)(scale*x1);
polys[i][c/3*2+1] = (int)(scale*z1);
}
}
}
public void draw(bool vectorMode, int x, int y, int[][] blocks, double inc, int s, Graphics g) {
scale = s;
angle1 += inc;
pickSides();
int[][] allPolys = new int[blocks.Length * 3][];
for (int b = 0; b < blocks.Length; b++) {
allPolys[b*3] = new int[10]; allPolys[b*3+1] = new int[10]; allPolys[b*3+2] = new int[10];
cube3d(blocks[b][0], blocks[b][1], blocks[b][2], new int[][] {allPolys[b*3], allPolys[b*3+1], allPolys[b*3+2]});
}
Array.Sort(allPolys, delegate(int[] a, int[] b) {
return a[8].CompareTo(b[8]);
});
for (int i = 0; i < allPolys.Length; i++) {
if (!vectorMode) {
g.setFG(colors[allPolys[i][9]][0], colors[allPolys[i][9]][1], colors[allPolys[i][9]][2]);
} else {
g.setFG(0,0,0);
}
g.tri("fill", x+allPolys[i][0],y+allPolys[i][1],
x+allPolys[i][2],y+allPolys[i][3], x+allPolys[i][6],y+allPolys[i][7]);
g.tri("fill", x+allPolys[i][6],y+allPolys[i][7],
x+allPolys[i][2],y+allPolys[i][3], x+allPolys[i][4],y+allPolys[i][5]);
if (vectorMode) {
g.setFG(0,255,0);
g.line(x+allPolys[i][0],y+allPolys[i][1], x+allPolys[i][2],y+allPolys[i][3]);
g.line(x+allPolys[i][2],y+allPolys[i][3], x+allPolys[i][4],y+allPolys[i][5]);
g.line(x+allPolys[i][4],y+allPolys[i][5], x+allPolys[i][6],y+allPolys[i][7]);
g.line(x+allPolys[i][6],y+allPolys[i][7], x+allPolys[i][0],y+allPolys[i][1]);
}
}
}
}
//--------------
//example usage:
//--------------
int[][] cubes = new int[][] {
SEFix.arr(0,0,0),
SEFix.arr(-1,0,0),
SEFix.arr(1,0,0),
SEFix.arr(1,1,0),
SEFix.arr(2,0,0),
SEFix.arr(1,2,0),
SEFix.arr(0,0,1),
SEFix.arr(1,0,-1)
};
Graphics graphics;
CubeViewer cv = new CubeViewer(-Math.PI/8); //y angle
void Main(string argument) {
if (graphics == null) {
List<IMyTerminalBlock> blocks2 = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyTextPanel>(blocks2, null);
graphics = new Graphics(160,160, (IMyTextPanel) blocks2[0]);
}
graphics.clear();
cv.draw(true, 80, 80, cubes, Math.PI / 32, 15, graphics);
graphics.paint();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment