Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Simple 3D Cube rendering example - by CJay
- //For an example on how to set up the display for this, check out my other workshop submissions.
- ///////////////////////////
- //tiny vector math library
- //I tried to use the VRageMath functions, but those seem to be broken in scripts
- //Instead I copied the parts I needed into here.
- public struct Vector3 {
- public float X;
- public float Y;
- public float Z;
- public Vector3(float x, float y, float z)
- {
- this.X = x;
- this.Y = y;
- this.Z = z;
- }
- public static Vector3 operator +(Vector3 value1, Vector3 value2)
- {
- Vector3 result;
- result.X = value1.X + value2.X;
- result.Y = value1.Y + value2.Y;
- result.Z = value1.Z + value2.Z;
- return result;
- }
- public static Vector3 operator -(Vector3 value1, Vector3 value2)
- {
- Vector3 result;
- result.X = value1.X - value2.X;
- result.Y = value1.Y - value2.Y;
- result.Z = value1.Z - value2.Z;
- return result;
- }
- //tiny hack - this converts the vector from device space (-1 .. +1) to screen space ( 0 .. 31 )
- public void Shift(float size) {
- this.X = ((this.X + 1f) * 0.5f) * size;
- this.Y = ((this.Y + 1f) * 0.5f) * size;
- this.Z = ((this.Z + 1f) * 0.5f) * size;
- }
- public static void Transform(ref Vector3 position, ref Matrix matrix, out Vector3 result)
- {
- float num = (float)((double)position.X * (double)matrix.M11 + (double)position.Y * (double)matrix.M21 + (double)position.Z * (double)matrix.M31) + matrix.M41;
- float num2 = (float)((double)position.X * (double)matrix.M12 + (double)position.Y * (double)matrix.M22 + (double)position.Z * (double)matrix.M32) + matrix.M42;
- float num3 = (float)((double)position.X * (double)matrix.M13 + (double)position.Y * (double)matrix.M23 + (double)position.Z * (double)matrix.M33) + matrix.M43;
- float num4 = 1f / (position.X * matrix.M14 + position.Y * matrix.M24 + position.Z * matrix.M34 + matrix.M44);
- result.X = num * num4;
- result.Y = num2 * num4;
- result.Z = num3 * num4;
- }
- }
- public struct Matrix {
- public float M11; public float M12; public float M13; public float M14;
- public float M21; public float M22; public float M23; public float M24;
- public float M31; public float M32; public float M33; public float M34;
- public float M41; public float M42; public float M43; public float M44;
- public static Matrix operator *(Matrix matrix1, Matrix matrix2)
- {
- Matrix result;
- result.M11 = (float)((double)matrix1.M11 * (double)matrix2.M11 + (double)matrix1.M12 * (double)matrix2.M21 + (double)matrix1.M13 * (double)matrix2.M31 + (double)matrix1.M14 * (double)matrix2.M41);
- result.M12 = (float)((double)matrix1.M11 * (double)matrix2.M12 + (double)matrix1.M12 * (double)matrix2.M22 + (double)matrix1.M13 * (double)matrix2.M32 + (double)matrix1.M14 * (double)matrix2.M42);
- result.M13 = (float)((double)matrix1.M11 * (double)matrix2.M13 + (double)matrix1.M12 * (double)matrix2.M23 + (double)matrix1.M13 * (double)matrix2.M33 + (double)matrix1.M14 * (double)matrix2.M43);
- result.M14 = (float)((double)matrix1.M11 * (double)matrix2.M14 + (double)matrix1.M12 * (double)matrix2.M24 + (double)matrix1.M13 * (double)matrix2.M34 + (double)matrix1.M14 * (double)matrix2.M44);
- result.M21 = (float)((double)matrix1.M21 * (double)matrix2.M11 + (double)matrix1.M22 * (double)matrix2.M21 + (double)matrix1.M23 * (double)matrix2.M31 + (double)matrix1.M24 * (double)matrix2.M41);
- result.M22 = (float)((double)matrix1.M21 * (double)matrix2.M12 + (double)matrix1.M22 * (double)matrix2.M22 + (double)matrix1.M23 * (double)matrix2.M32 + (double)matrix1.M24 * (double)matrix2.M42);
- result.M23 = (float)((double)matrix1.M21 * (double)matrix2.M13 + (double)matrix1.M22 * (double)matrix2.M23 + (double)matrix1.M23 * (double)matrix2.M33 + (double)matrix1.M24 * (double)matrix2.M43);
- result.M24 = (float)((double)matrix1.M21 * (double)matrix2.M14 + (double)matrix1.M22 * (double)matrix2.M24 + (double)matrix1.M23 * (double)matrix2.M34 + (double)matrix1.M24 * (double)matrix2.M44);
- result.M31 = (float)((double)matrix1.M31 * (double)matrix2.M11 + (double)matrix1.M32 * (double)matrix2.M21 + (double)matrix1.M33 * (double)matrix2.M31 + (double)matrix1.M34 * (double)matrix2.M41);
- result.M32 = (float)((double)matrix1.M31 * (double)matrix2.M12 + (double)matrix1.M32 * (double)matrix2.M22 + (double)matrix1.M33 * (double)matrix2.M32 + (double)matrix1.M34 * (double)matrix2.M42);
- result.M33 = (float)((double)matrix1.M31 * (double)matrix2.M13 + (double)matrix1.M32 * (double)matrix2.M23 + (double)matrix1.M33 * (double)matrix2.M33 + (double)matrix1.M34 * (double)matrix2.M43);
- result.M34 = (float)((double)matrix1.M31 * (double)matrix2.M14 + (double)matrix1.M32 * (double)matrix2.M24 + (double)matrix1.M33 * (double)matrix2.M34 + (double)matrix1.M34 * (double)matrix2.M44);
- result.M41 = (float)((double)matrix1.M41 * (double)matrix2.M11 + (double)matrix1.M42 * (double)matrix2.M21 + (double)matrix1.M43 * (double)matrix2.M31 + (double)matrix1.M44 * (double)matrix2.M41);
- result.M42 = (float)((double)matrix1.M41 * (double)matrix2.M12 + (double)matrix1.M42 * (double)matrix2.M22 + (double)matrix1.M43 * (double)matrix2.M32 + (double)matrix1.M44 * (double)matrix2.M42);
- result.M43 = (float)((double)matrix1.M41 * (double)matrix2.M13 + (double)matrix1.M42 * (double)matrix2.M23 + (double)matrix1.M43 * (double)matrix2.M33 + (double)matrix1.M44 * (double)matrix2.M43);
- result.M44 = (float)((double)matrix1.M41 * (double)matrix2.M14 + (double)matrix1.M42 * (double)matrix2.M24 + (double)matrix1.M43 * (double)matrix2.M34 + (double)matrix1.M44 * (double)matrix2.M44);
- return result;
- }
- public void CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
- {
- float num = 1f / (float)Math.Tan((double)fieldOfView * 0.5);
- float m = num / aspectRatio;
- this.M11 = m;
- this.M12 = (this.M13 = (this.M14 = 0f));
- this.M22 = num;
- this.M21 = (this.M23 = (this.M24 = 0f));
- this.M31 = (this.M32 = 0f);
- this.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance);
- this.M34 = -1f;
- this.M41 = (this.M42 = (this.M44 = 0f));
- this.M43 = (float)((double)nearPlaneDistance * (double)farPlaneDistance / ((double)nearPlaneDistance - (double)farPlaneDistance));
- }
- public void CreateRotationX(float radians)
- {
- float num = (float)Math.Cos((double)radians);
- float num2 = (float)Math.Sin((double)radians);
- this.M11 = 1f;
- this.M12 = 0f;
- this.M13 = 0f;
- this.M14 = 0f;
- this.M21 = 0f;
- this.M22 = num;
- this.M23 = num2;
- this.M24 = 0f;
- this.M31 = 0f;
- this.M32 = -num2;
- this.M33 = num;
- this.M34 = 0f;
- this.M41 = 0f;
- this.M42 = 0f;
- this.M43 = 0f;
- this.M44 = 1f;
- }
- public void CreateRotationY(float radians)
- {
- float num = (float)Math.Cos((double)radians);
- float num2 = (float)Math.Sin((double)radians);
- this.M11 = num;
- this.M12 = 0f;
- this.M13 = -num2;
- this.M14 = 0f;
- this.M21 = 0f;
- this.M22 = 1f;
- this.M23 = 0f;
- this.M24 = 0f;
- this.M31 = num2;
- this.M32 = 0f;
- this.M33 = num;
- this.M34 = 0f;
- this.M41 = 0f;
- this.M42 = 0f;
- this.M43 = 0f;
- this.M44 = 1f;
- }
- public void CreateTranslation(float xPosition, float yPosition, float zPosition)
- {
- this.M11 = 1f;
- this.M12 = 0f;
- this.M13 = 0f;
- this.M14 = 0f;
- this.M21 = 0f;
- this.M22 = 1f;
- this.M23 = 0f;
- this.M24 = 0f;
- this.M31 = 0f;
- this.M32 = 0f;
- this.M33 = 1f;
- this.M34 = 0f;
- this.M41 = xPosition;
- this.M42 = yPosition;
- this.M43 = zPosition;
- this.M44 = 1f;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //This class is what talks to the display
- public class DisplayController {
- public int ResX, ResY;
- Program prog;
- List<IMyTerminalBlock> lights;
- public DisplayController(int rx, int ry, Program p, List<IMyTerminalBlock> l) {
- prog = p;
- ResX = rx;
- ResY = ry;
- lights = l;
- }
- public void Flush() {
- for(int i = 0; i < lights.Count; i++) {
- if (((IMyFunctionalBlock)lights[i]).Enabled) {
- lights[i].GetActionWithName("OnOff_Off").Apply(lights[i]);
- }
- }
- }
- public void SetPixel(int x, int y, bool state) {
- int number = x * ResY + y;
- /*
- if (number < 0) {
- throw new Exception("Pixel index below zero! (" + number);
- }
- if (number >= (lights.Count - 1)) {
- throw new Exception("Pixel index exceeds pixel count! (" + number + " , " + lights.Count);
- }
- */
- if ((number >= 0) && (number < lights.Count)) {
- if (state) {
- lights[number].GetActionWithName("OnOff_On").Apply(lights[number]);
- } else {
- lights[number].GetActionWithName("OnOff_Off").Apply(lights[number]);
- }
- }
- }
- }
- public class Renderer {
- //I'd prefer to have every line as its own object - but it won't work for some reason
- List<Vector3> startPoints = new List<Vector3>();
- List<Vector3> endPoints = new List<Vector3>();
- Matrix mvp = new Matrix();
- Matrix model = new Matrix();
- Matrix view = new Matrix();
- Matrix projection = new Matrix();
- public Vector3 campos = new Vector3(0f, 0f, 2.25f);
- public Renderer(DisplayController dc) {
- //Prepare the projection matrix - this essentially sets the camera parameters
- projection.CreatePerspectiveFieldOfView(
- 1.7f, //Field of view, in radians (1.7 is about 97°)
- 1f, //Aspect ratio
- 0.1f, //Near clip, ie something 0.1 units away from the camera will be at Z position -1 in device space
- 100f //Far clip, ie something 100 units away from the camera will be at Z position +1 in device space
- );
- display = dc;
- }
- public DisplayController display;
- //borrowed and butchered from http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm
- private void Swap(ref int lhs, ref int rhs) { int temp; temp = lhs; lhs = rhs; rhs = temp; }
- public void Line(int x0, int y0, int x1, int y1, bool set) {
- bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
- if (steep) { Swap(ref x0, ref y0); Swap(ref x1, ref y1); }
- if (x0 > x1) { Swap(ref x0, ref x1); Swap(ref y0, ref y1); }
- int dX = (x1 - x0), dY = Math.Abs(y1 - y0), err = (dX / 2), ystep = (y0 < y1 ? 1 : -1), y = y0;
- for (int x = x0; x <= x1; ++x)
- {
- if (steep) {
- display.SetPixel(y, x, set);
- } else {
- display.SetPixel(x, y, set);
- }
- err = err - dY;
- if (err < 0) { y += ystep; err += dX; }
- }
- }
- public void AddLine(Vector3 start, Vector3 end) {
- startPoints.Add(start);
- endPoints.Add(end);
- }
- public void PreProcess(float t) {
- //This functions prepares the transformation matrix used during rendering.
- //First we make a temporary rotation matrix around the X axis
- Matrix trot = new Matrix();
- trot.CreateRotationX(t);
- //Then we set our model matrix to a rotation matrix around the Y axis
- model.CreateRotationY(t);
- //Now we combine both into the model matrix. Now the model matrix rotates around both axis.
- model = model * trot;
- //Now we create the view matrix from the camera position
- view.CreateTranslation(campos.X, campos.Y, campos.Z);
- //Lastly we compute the Model-View-Projection (MVP) matrix.
- //It combines the model position, view position and perspective distortion into one matrix.
- mvp = model * view * projection;
- }
- public void Render(bool set) {
- //Iterate through every line
- for (int i = 0; i < startPoints.Count; ++i) {
- //These vectors will hold the transformed values later
- Vector3 tr_s = new Vector3(0f, 0f, 0f);
- Vector3 tr_e = new Vector3(0f, 0f, 0f);
- //Get the object-space coordinates
- Vector3 s = startPoints[i];
- Vector3 e = endPoints[i];
- //Apply the transformation matrix
- Vector3.Transform(ref s, ref mvp, out tr_s);
- Vector3.Transform(ref e, ref mvp, out tr_e);
- //shift it into screen space
- tr_s.Shift(display.ResX);
- tr_e.Shift(display.ResX);
- //Now draw the line!
- try {
- Line(Convert.ToInt32(tr_s.X), Convert.ToInt32(tr_s.Y), Convert.ToInt32(tr_e.X), Convert.ToInt32(tr_e.Y), set);
- } catch (Exception ex) {
- throw new Exception("error while drawing line");
- }
- }
- }
- }
- bool init = false;
- bool preprocess = true;
- float t = 0.0f;
- DisplayController dc;
- Renderer renderer;
- int DISP_WIDTH = 32;
- int DISP_HEIGHT = 32;
- Vector3 cpos = new Vector3(0f, 0f, 2.25f);
- void Main()
- {
- if (!init) {
- List<IMyTerminalBlock> l = new List<IMyTerminalBlock>();
- GridTerminalSystem.GetBlocksOfType<IMyThrust>(l);
- dc = new DisplayController(DISP_WIDTH, DISP_HEIGHT, this, l);
- //dc.Flush();
- renderer = new Renderer(dc);
- init = true;
- //This defines all the corners of our cube.
- Vector3 p1 = new Vector3(-1f, -1f, -1f);
- Vector3 p2 = new Vector3( 1f, -1f, -1f);
- Vector3 p3 = new Vector3(-1f, -1f, 1f);
- Vector3 p4 = new Vector3( 1f, -1f, 1f);
- Vector3 p5 = new Vector3(-1f, 1f, -1f);
- Vector3 p6 = new Vector3( 1f, 1f, -1f);
- Vector3 p7 = new Vector3(-1f, 1f, 1f);
- Vector3 p8 = new Vector3( 1f, 1f, 1f);
- //Now we tell the renderer which points to connect with a line
- renderer.AddLine(p1, p2);
- renderer.AddLine(p3, p4);
- renderer.AddLine(p5, p6);
- renderer.AddLine(p7, p8);
- renderer.AddLine(p1, p3);
- renderer.AddLine(p2, p4);
- renderer.AddLine(p5, p7);
- renderer.AddLine(p6, p8);
- renderer.AddLine(p1, p5);
- renderer.AddLine(p2, p6);
- renderer.AddLine(p3, p7);
- renderer.AddLine(p4, p8);
- }
- //I was hitting the performance limit for scripts - so I split the matrix computation into an extra pass.
- if (preprocess) {
- renderer.PreProcess(t);
- } else {
- dc.Flush();
- renderer.Render(true);
- t += 0.05f;
- }
- preprocess = !preprocess;
- }
Advertisement
Add Comment
Please, Sign In to add comment