Giter Site home page Giter Site logo

atmega328-tiny-3d-engine's People

Contributors

mrt-prodz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

atmega328-tiny-3d-engine's Issues

python 3 is not supported by stl2h, so here is the conversation for python3

//python 3 is not supported by stl2h.py , so here is the conversation for python3..
//online formatting of text might be incorrect so copy and put into a file.. i'm hesitant to change original file at this point
//and leave it up to original authors..
//modified by james villeneuve in 2022 for stl to file conversion for arduino stl files for tiny 3d engine
//using https://www.tutorialspoint.com/online_python_formatter.htm to clean up tab issues
//and using a python 2to3 converter online tool https://python2to3.com/#!/usr/bin/python
//just save in any working directory as stl2h.py
// to use you will most likely need to decimate stl file to under 700 faces in blender and then
//use a program like meshlab to convert it from binary stl to text based output.
//below is an example that uses a file called my_stl_file.stl output file text.txt and scales item by 5.
//example use is python3 stl2h.py -i my_stl_file.stl -o text.txt -s 5

file for python3 is here. https://github.com/jamesdanielv/pyhton3convertof-stl2h.py

License to use

I do not see a license for this software. Is it public-domain or what is the license to modify and redistribute?

Compiler error for Arduino 1.8.5

Hi,

I have ardiuno uno board interfaced with TFT screen st7735 and when I use your code it shows me an error in compiling .

C:\Users\Haaris Moosa\Desktop\arduino-1.8.5\hardware\tools\avr/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -w -flto -fuse-linker-plugin -o tiny_3d_engine:157: error: unable to find a register to spill in class 'POINTER_REGS'

I have only listed the errors which are useful

I googled it and it's a gcc compiler error. I'm using gcc 4.9.2
Can you please share your gcc version and the Arduino IDE version that you were using?

Objects with more than 256 TRIS

Hello,
Thanks for this nice engine.
I was able to use it on a Teensy 3.6 with an SSD1306 Oled display at 128x64.

There is only a problem with STL objects TRIcount > 256 in wireframe mode.
Only the first 256 tris are rendered correctly. The rest is rendered in "random" line coordinates.
Vertex mode seems to work correctly wit more than 256 nodes.

I changed the datatype in stl2h.py -> const unsigned char faces[TRICOUNT][3]
to const unsigned short int faces[TRICOUNT][3].

also in the Arduino sketch i changed a lot to widen the data type ranges.

I just cant figure out what the real problem is.
Any help is very appreciated! Thanks!

The planes look like a grid mesh. >> objects.zip

// =============================================================================
// Arduino - Tiny 3D Engine
// =============================================================================
// ----------------------------------------------
// includes
// ----------------------------------------------
#include "type.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(4);

// ----------------------------------------------
// meshes
// ----------------------------------------------
//#include "mesh_cube.h"
//#include "mesh_cone.h"
//#include "mesh_sphere.h"
//#include "mesh_torus.h"
//#include "mesh_monkey.h"
#include "plane.h"
//#include "planeLow.h"



// ----------------------------------------------
// defines
// ----------------------------------------------
#define HALFW            64
#define HALFH            32
#define FOV              64
#define SKIP_TICKS       20.0                // 50fps
#define MAX_FRAMESKIP    3

#define LUT(a) (long)(pgm_read_word(&lut[a]))// return value from LUT in PROGMEM

// ----------------------------------------------
// global variables
// ----------------------------------------------
Matrix4 m_world;
Vector3i mesh_rotation = {0, 0, 0};
Vector3i mesh_position = {0, 0, 0};

const unsigned int lut[] PROGMEM = {         // 0 to 90 degrees fixed point COSINE look up table
  16384, 16381, 16374, 16361, 16344, 16321, 16294, 16261, 16224, 16182, 16135, 16082, 16025, 15964, 15897, 15825, 15749, 15668, 15582, 15491, 15395, 15295, 15190, 15081, 14967, 14848, 14725, 14598, 14466, 14329, 14188, 14043, 13894, 13740, 13582, 13420, 13254, 13084, 12910, 12732, 12550, 12365, 12175, 11982, 11785, 11585, 11381, 11173, 10963, 10748, 10531, 10310, 10086, 9860, 9630, 9397, 9161, 8923, 8682, 8438, 8191, 7943, 7691, 7438, 7182, 6924, 6663, 6401, 6137, 5871, 5603, 5334, 5062, 4790, 4516, 4240, 3963, 3685, 3406, 3126, 2845, 2563, 2280, 1996, 1712, 1427, 1142, 857, 571, 285, 0
};

static long proj_nodes[NODECOUNT][2];         // projected nodes (x,y)
//static int old_nodes[NODECOUNT][2];        // projected nodes of previous frame to check if we need to redraw
static long i;
static int loops;
static double next_tick;
static double last_btn;                      // used for checking when the button was last pushed


// ----------------------------------------------
// SIN/COS from 90 degrees LUT
// ----------------------------------------------
long SIN(unsigned int angle) {
  angle += 90;
  if (angle > 450) return LUT(0);
  if (angle > 360 && angle < 451) return -LUT(angle - 360);
  if (angle > 270 && angle < 361) return -LUT(360 - angle);
  if (angle > 180 && angle < 271) return  LUT(angle - 180);
  return LUT(180 - angle);
}

long COS(unsigned int angle) {
  if (angle > 360) return LUT(0);
  if (angle > 270 && angle < 361) return  LUT(360 - angle);
  if (angle > 180 && angle < 271) return -LUT(angle - 180);
  if (angle > 90  && angle < 181) return -LUT(180 - angle);
  return LUT(angle);
}

// ----------------------------------------------
// Matrix operation
// ----------------------------------------------
Matrix4 mMultiply(const Matrix4 &mat1, const Matrix4 &mat2) {
  Matrix4 mat;
  unsigned char r, c;
  for (c = 0; c < 4; c++)
    for (r = 0; r < 4; r++)
      mat.m[c][r] = pMultiply(mat1.m[0][r], mat2.m[c][0]) +
                    pMultiply(mat1.m[1][r], mat2.m[c][1]) +
                    pMultiply(mat1.m[2][r], mat2.m[c][2]) +
                    pMultiply(mat1.m[3][r], mat2.m[c][3]);
  return mat;
}

Matrix4 mRotateX(const unsigned int angle) {
  Matrix4 mat;
  mat.m[1][1] =  COS(angle);
  mat.m[1][2] =  SIN(angle);
  mat.m[2][1] = -SIN(angle);
  mat.m[2][2] =  COS(angle);
  return mat;
}

Matrix4 mRotateY(const unsigned int angle) {
  Matrix4 mat;
  mat.m[0][0] =  COS(angle);
  mat.m[0][2] = -SIN(angle);
  mat.m[2][0] =  SIN(angle);
  mat.m[2][2] =  COS(angle);
  return mat;
}

Matrix4 mRotateZ(const unsigned int angle) {
  Matrix4 mat;
  mat.m[0][0] =  COS(angle);
  mat.m[0][1] =  SIN(angle);
  mat.m[1][0] = -SIN(angle);
  mat.m[1][1] =  COS(angle);
  return mat;
}

Matrix4 mTranslate(const long x, const long y, const long z) {
  Matrix4 mat;
  mat.m[3][0] =  x << PSHIFT;
  mat.m[3][1] =  y << PSHIFT;
  mat.m[3][2] =  z << PSHIFT;
  return mat;
}

Matrix4 mScale(const float ratio) {
  Matrix4 mat;
  mat.m[0][0] *= ratio;
  mat.m[1][1] *= ratio;
  mat.m[2][2] *= ratio;
  return mat;
}

// ----------------------------------------------
// Shoelace algorithm to get the surface
// ----------------------------------------------
int shoelace(const int (*n)[2], const unsigned short int index) {
  unsigned short int t = 0;
  int surface = 0;
  for (; t < 3; t++) {
    // (x1y2 - y1x2) + (x2y3 - y2x3) ...
    surface += (n[EDGE(index, t)][0]           * n[EDGE(index, (t < 2 ? t + 1 : 0))][1]) -
               (n[EDGE(index, (t < 2 ? t + 1 : 0))][0] * n[EDGE(index, t)][1]);
  }
  return surface * 0.5;
}

// ----------------------------------------------
// Shoelace algorithm for triangle visibility
// ----------------------------------------------
bool is_hidden(const int (*n)[2], const unsigned short int index) {
  // (x1y2 - y1x2) + (x2y3 - y2x3) ...
  return ( ( (n[EDGE(index, 0)][0] * n[EDGE(index, 1)][1]) -
             (n[EDGE(index, 1)][0] * n[EDGE(index, 0)][1])   ) +
           ( (n[EDGE(index, 1)][0] * n[EDGE(index, 2)][1]) -
             (n[EDGE(index, 2)][0] * n[EDGE(index, 1)][1])   ) +
           ( (n[EDGE(index, 2)][0] * n[EDGE(index, 0)][1]) -
             (n[EDGE(index, 0)][0] * n[EDGE(index, 2)][1])   ) ) < 0 ? false : true;
}

// ----------------------------------------------
// draw projected nodes
// ----------------------------------------------
void draw_vertex(const int (*n)[2]) {
  i = NODECOUNT - 1;
  do {
    display.drawPixel(n[i][0], n[i][1], WHITE);
  } while (i--);
}

// ----------------------------------------------
// draw edges between projected nodes
// ----------------------------------------------
void draw_wireframe(const long (*n)[2]) {
  i = TRICOUNT - 1;
  int NR1 = 0;
  int NR2 = 1;

  do {

    display.setCursor(0, 0);
    display.fillRect(0, 0, 32, 32, BLACK);
    display.print(i);
    display.setCursor(0, 8);
    display.print(NR2);
    display.setCursor(0, 16);
    display.print(n[EDGE(i, 0)][0]);
    display.print(":");
    display.print(n[EDGE(i, 0)][1]);
    display.setCursor(0, 24);
    display.print(n[EDGE(i, 1)][0]);
    display.print(":");
    display.print(n[EDGE(i, 1)][1]);
    
    

    // don't draw triangle with negative surface value
    //if (!is_hidden(n, i)) {
    // draw triangle edges - 0 -> 1 -> 2 -> 0
    display.drawLine(n[EDGE(i, 0)][0], n[EDGE(i, 0)][1], n[EDGE(i, 1)][0], n[EDGE(i, 1)][1], WHITE);
    display.drawLine(n[EDGE(i, 1)][0], n[EDGE(i, 1)][1], n[EDGE(i, 2)][0], n[EDGE(i, 2)][1], WHITE);
    display.drawLine(n[EDGE(i, 2)][0], n[EDGE(i, 2)][1], n[EDGE(i, 0)][0], n[EDGE(i, 0)][1], WHITE);
    //}

    NR1++;
    NR2++;
    if (NR1 >= 255) 
    { 
    NR1 = 0;
    display.clearDisplay(); 
    }

    display.display();

  } while (i--);

  delay(3000);
}


// ----------------------------------------------
// write current drawing mode in corner of screen
// ----------------------------------------------
void draw_print(unsigned short int wert) {
  display.setCursor(0, 0);
  //display.println(F(" wireframe"));
  //display.print(F(" triangles: "));
  //display.println(TRICOUNT);
  display.fillRect(0, 0, 23, 7, BLACK);
  display.print(wert);

}

// ----------------------------------------------
// setup
// ----------------------------------------------
void setup() {

  // initialize screen
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.display();
  display.clearDisplay();
  // print draw type on screen
  //draw_print();
  // init tick
  next_tick = last_btn = millis();
}

// ----------------------------------------------
// main loop
// ----------------------------------------------
void loop() {
  loops = 0;
  //while ( millis() > next_tick && loops < MAX_FRAMESKIP) {

  // rotation
  m_world = mRotateX(mesh_rotation.x);
  m_world = mMultiply(mRotateY(mesh_rotation.y), m_world);
  m_world = mMultiply(mRotateZ(mesh_rotation.z), m_world);
  // scaling
  //m_world = mMultiply(mScale(1.5), m_world);

  // project nodes with world matrix
  Vector3i p;
  for (i = 0; i < NODECOUNT; i++) {
    p.x = (m_world.m[0][0] * (NODE(i, 0) >> PSHIFT) +
           m_world.m[1][0] * (NODE(i, 1) >> PSHIFT) +
           m_world.m[2][0] * (NODE(i, 2) >> PSHIFT) +
           m_world.m[3][0]) / PRES;

    p.y = (m_world.m[0][1] * (NODE(i, 0) >> PSHIFT) +
           m_world.m[1][1] * (NODE(i, 1) >> PSHIFT) +
           m_world.m[2][1] * (NODE(i, 2) >> PSHIFT) +
           m_world.m[3][1]) / PRES;

    p.z = (m_world.m[0][2] * (NODE(i, 0) >> PSHIFT) +
           m_world.m[1][2] * (NODE(i, 1) >> PSHIFT) +
           m_world.m[2][2] * (NODE(i, 2) >> PSHIFT) +
           m_world.m[3][2]) / PRES;

    // store projected node
    proj_nodes[i][0] = (FOV * p.x) / (FOV + p.z) + HALFW;
    proj_nodes[i][1] = (FOV * p.y) / (FOV + p.z) + HALFH;
  }

  // default auto-rotation mode
  //mesh_rotation.x += 3;   // |
  //mesh_rotation.y += 2;   // -
  //mesh_rotation.z++;      // O

  if (mesh_rotation.x > 360) mesh_rotation.x = 0;
  if (mesh_rotation.y > 360) mesh_rotation.y = 0;
  if (mesh_rotation.z > 360) mesh_rotation.z = 0;

  next_tick += SKIP_TICKS;
  loops++;
  //}


  //DRAW

  display.clearDisplay();
  draw_wireframe(proj_nodes);
  //draw_vertex(proj_nodes);
  display.display();
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.