diff --git a/README.md b/README.md
index dbf3ee2a..04737b6a 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,14 @@ Two caps and many strips composites a cylinder.
Almost all 3D editor have a infinite grid ground, I just made a finite one, in the future, I should expand the grid outside of the screen to make it infinite.
Now, for just beginning, I think it's a not bad start.
-- [ ] Implement B-Mesh algorithm
+- [ ] Implement B-Mesh algorithm (Dec 18, 2016 ~ Dec 19, 2016)
+*Drawing Skeletal Shape Balls*
+Draw shape ball is easy, no need to rotate, I just need scale it along the ball's radius.
+Draw the cylinder which connects two shape balls is more difficult, I need do some math to rotate it. [Here](http://www.thjsmith.com/40/cylinder-between-two-points-opengl-c) described it.
+*Camera Control*
+Camera rotate/zoom implemented, [here](http://www.songho.ca/opengl/gl_transform.html) is a good article which explained the theory of OpenGL Transformation. Most important is the demo apps all are very beautiful.
+
+Added x,z axis, looks better than last screenshot.
- [ ] Export Wavefront .obj
- [ ] Render B-Mesh result
- [ ] Design UI for monster parts configuration
diff --git a/build/dust3d.pro b/build/dust3d.pro
index fd47d561..5c8eef14 100644
--- a/build/dust3d.pro
+++ b/build/dust3d.pro
@@ -8,11 +8,17 @@ INCLUDEPATH += ../src
SOURCES += main.cpp \
mainwindow.cpp \
- glwidget.cpp \
- drawcommon.c \
- drawsphere.c
+ render.cpp \
+ vector3d.c \
+ draw.cpp \
+ array.c \
+ bmesh.c \
+ matrix.c
HEADERS += mainwindow.h \
- glwidget.h \
- drawcommon.h \
- drawsphere.h
\ No newline at end of file
+ render.h \
+ vector3d.h \
+ draw.h \
+ array.h \
+ bmesh.h \
+ matrix.h
\ No newline at end of file
diff --git a/src/drawcommon.c b/src/drawcommon.c
deleted file mode 100644
index 8f31acd8..00000000
--- a/src/drawcommon.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "drawcommon.h"
-#include
-
-void normalize(point *p) {
- double mag;
- mag = p->x * p->x + p->y * p->y + p->z * p->z;
- if (mag != 0.0) {
- mag = 1.0 / sqrt(mag);
- p->x *= mag;
- p->y *= mag;
- p->z *= mag;
- }
-}
-
-void midpoint(point *a, point *b, point *mid) {
- mid->x = (a->x + b->x) * 0.5;
- mid->y = (a->y + b->y) * 0.5;
- mid->z = (a->z + b->z) * 0.5;
-}
-
diff --git a/src/drawsphere.c b/src/drawsphere.c
deleted file mode 100644
index 02f825b1..00000000
--- a/src/drawsphere.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "drawcommon.h"
-#include "drawsphere.h"
-#include
-#include
-#include
-
-/*
- * This function modified from [Jon Leech's implementation of sphere](ftp://ftp.ee.lbl.gov/sphere.c)
- * Jeremy HU (huxingyi@msn.com) 2016/12/16
-*/
-
-#define XPLUS { 1, 0, 0 } /* X */
-#define XMIN { -1, 0, 0 } /* -X */
-#define YPLUS { 0, 1, 0 } /* Y */
-#define YMIN { 0, -1, 0 } /* -Y */
-#define ZPLUS { 0, 0, 1 } /* Z */
-#define ZMIN { 0, 0, -1 } /* -Z */
-
-static const triangle octahedron[] = {
- {{XPLUS, ZPLUS, YPLUS}},
- {{YPLUS, ZPLUS, XMIN}},
- {{XMIN, ZPLUS, YMIN}},
- {{YMIN, ZPLUS, XPLUS}},
- {{XPLUS, YPLUS, ZMIN}},
- {{YPLUS, XMIN, ZMIN}},
- {{XMIN, YMIN, ZMIN}},
- {{YMIN, XPLUS, ZMIN}},
-};
-
-static void subdivide(object *old, object *subdivided) {
- int i;
- for (i = 0; i < old->npoly; ++i) {
- triangle *oldt = &old->poly[i];
- triangle *newt = &subdivided->poly[i * 4];
- point a, b, c;
-
- midpoint(&oldt->pt[0], &oldt->pt[2], &a);
- midpoint(&oldt->pt[0], &oldt->pt[1], &b);
- midpoint(&oldt->pt[1], &oldt->pt[2], &c);
-
- normalize(&a);
- normalize(&b);
- normalize(&c);
-
- newt->pt[0] = oldt->pt[0];
- newt->pt[1] = b;
- newt->pt[2] = a;
- newt++;
-
- newt->pt[0] = b;
- newt->pt[1] = oldt->pt[1];
- newt->pt[2] = c;
- newt++;
-
- newt->pt[0] = a;
- newt->pt[1] = b;
- newt->pt[2] = c;
- newt++;
-
- newt->pt[0] = a;
- newt->pt[1] = c;
- newt->pt[2] = oldt->pt[2];
- }
-}
-
-int drawSphere(int level) {
- int lv, i;
- object oldObj, newObj;
-
- if (level < 1) {
- fprintf(stderr, "%s:level max greater than 0.\n", __FUNCTION__);
- return -1;
- }
-
- oldObj.npoly = sizeof(octahedron) / sizeof(octahedron[0]);
- oldObj.poly = (triangle *)malloc(oldObj.npoly * sizeof(triangle));
- if (!oldObj.poly) {
- fprintf(stderr, "%s:insufficient memory.\n", __FUNCTION__);
- return -1;
- }
- memcpy(oldObj.poly, octahedron, oldObj.npoly * sizeof(triangle));
-
- for (lv = 0; lv < level; lv++) {
- newObj.npoly = oldObj.npoly * 4;
- newObj.poly = (triangle *)malloc(newObj.npoly * sizeof(triangle));
- if (!newObj.poly) {
- fprintf(stderr, "%s:insufficient memory(levelLoop:%d).\n",
- __FUNCTION__, lv);
- free(oldObj.poly);
- return -1;
- }
-
- subdivide(&oldObj, &newObj);
-
- free(oldObj.poly);
- oldObj = newObj;
- }
-
- for (i = 0; i < newObj.npoly; ++i) {
- drawTriangle(&newObj.poly[i]);
- }
-
- free(newObj.poly);
-
- return 0;
-}
diff --git a/src/drawsphere.h b/src/drawsphere.h
deleted file mode 100644
index 3d6a9929..00000000
--- a/src/drawsphere.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef DRAW_SPHERE_H
-#define DRAW_SPHERE_H
-#include "drawcommon.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int drawSphere(int level);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/glwidget.cpp b/src/glwidget.cpp
deleted file mode 100644
index ffdedcef..00000000
--- a/src/glwidget.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-#include
-#include
-#include
-#include
-#include "glwidget.h"
-#include "drawcommon.h"
-#include "drawsphere.h"
-
-void drawTriangle(triangle *poly) {
- int i;
- glBegin(GL_TRIANGLES);
- for (i = 0; i < 3; ++i) {
- point *pt = &poly->pt[i];
- glNormal3f(pt->x, pt->y, pt->z);
- glVertex3f(pt->x, pt->y, pt->z);
- }
- glEnd();
-}
-
-int drawCylinder(int slices, float radius, float height) {
- float theta = (2.0 * M_PI) / (float)slices;
- float a = 0.0f;
- int lv;
- float halfHeight = height / 2;
- float x, y, z;
-
- if (slices <= 0) {
- fprintf(stderr, "%s:Invalid parameter(slices:%d).\n", __FUNCTION__, slices);
- return -1;
- }
-
- // strips
- glBegin(GL_TRIANGLE_STRIP);
- for (a = 0, lv = 0; lv <= slices; ++lv) {
- float cosa = cos(a);
- float sina = sin(a);
- x = cosa * radius;
- y = sina * radius;
- z = -halfHeight;
- glNormal3f(cosa, sina, 0);
- glVertex3f(x, y, z);
- z = halfHeight;
- glNormal3f(cosa, sina, 0);
- glVertex3f(x, y, z);
- a += theta;
- }
- glEnd();
-
- // bottom cap
- z = -halfHeight;
- glBegin(GL_TRIANGLE_FAN);
- glNormal3f(0, 0, -1);
- glVertex3f(0, 0, z);
- for (a = 0, lv = 0; lv <= slices; ++lv) {
- x = cos(a) * radius;
- y = sin(a) * radius;
- glNormal3f(0, 0, -1);
- glVertex3f(x, y, z);
- a += theta;
- }
- glEnd();
-
- // top cap
- z = halfHeight;
- glBegin(GL_TRIANGLE_FAN);
- glNormal3f(0, 0, 1);
- glVertex3f(0, 0, z);
- for (a = 0, lv = 0; lv <= slices; ++lv) {
- x = cos(a) * radius;
- y = sin(a) * radius;
- glNormal3f(0, 0, 1);
- glVertex3f(x, y, z);
- a += theta;
- }
- glEnd();
-
- return 0;
-}
-
-GLWidget::GLWidget(QWidget *parent)
- : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) {
- QTimer *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(update()));
- timer->start(100);
-}
-
-GLWidget::~GLWidget() {
-}
-
-void GLWidget::initializeGL() {
- GLfloat mat_ambient[] = { 0.0 , 0.0 , 0.0 , 1.0 };
- GLfloat mat_diffuse[] = { 0.55 , 0.55 , 0.55 , 1.0 };
- GLfloat mat_specular[] = {0.7 , 0.7 , 0.7, 1.0 };
- GLfloat mat_shininess[] = { 32 };
-
- GLfloat light_diffuse[] = { 1.0 , 1.0 , 1.0 , 1.0 };
- GLfloat light_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 };
- GLfloat light_ambient[] = { 0.2 , 0.2 , 0.2 , 1.0 };
- GLfloat light_position[] = { -1,1,1 , 0 };
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glShadeModel(GL_SMOOTH);
-
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
-
- glLightfv(GL_LIGHT0 , GL_POSITION , light_position);
- glLightfv(GL_LIGHT0 , GL_DIFFUSE , light_diffuse);
- glLightfv(GL_LIGHT0 , GL_AMBIENT , light_ambient);
- glLightfv(GL_LIGHT0 , GL_SPECULAR , light_specular);
-
- glDepthFunc(GL_LESS);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
-}
-
-void GLWidget::paintGL() {
- static int angle = 0;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glBegin(GL_LINES);
- for (GLfloat i = -2.5; i <= 2.5; i += 0.25) {
- glVertex3f(i, 0, 2.5); glVertex3f(i, 0, -2.5);
- glVertex3f(2.5, 0, i); glVertex3f(-2.5, 0, i);
- }
- glEnd();
-
- drawSphere(4);
-
- glPushMatrix();
- glRotatef(angle, 1, 1, 0);
- angle = (angle + 1) % 360;
- drawCylinder(40, 0.2, 2.1);
- glPopMatrix();
-}
-
-void GLWidget::resizeGL(int w, int h) {
- glViewport(0, 0, (GLsizei)w, (GLsizei)h);
-
- glClearColor(0.92, 0.92, 0.92, 1.0);
- glColor3f(1.0, 1.0, 1.0);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-2, 2, -1.5, 1.5, 1, 10);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0, 0, -2);
- glRotatef(50, 1, 0, 0);
- glRotatef(70, 0, 1, 0);
-}
-
-void GLWidget::mousePressEvent(QMouseEvent *event) {
-}
-
-void GLWidget::mouseMoveEvent(QMouseEvent *event) {
-}
diff --git a/src/glwidget.h b/src/glwidget.h
deleted file mode 100644
index e18370b0..00000000
--- a/src/glwidget.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef GLWIDGET_H
-#define GLWIDGET_H
-
-#include
-
-class GLWidget : public QGLWidget
-{
- Q_OBJECT
-
-public:
- GLWidget(QWidget *parent = 0);
- ~GLWidget();
-
-protected:
- void initializeGL();
- void paintGL();
- void resizeGL(int width, int height);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
-};
-
-#endif