stereoview

changeset 0:dc1723a8bf6f

initial import
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 04 Mar 2011 06:51:16 +0200
parents
children 59fd3f6948fe 30c7a5df0523
files Makefile src/cam.cc src/cam.h src/stereoview.cc src/zscn.cc src/zscn.h
diffstat 6 files changed, 628 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Makefile	Fri Mar 04 06:51:16 2011 +0200
     1.3 @@ -0,0 +1,20 @@
     1.4 +src = $(wildcard src/*.cc)
     1.5 +obj = $(src:.cc=.o)
     1.6 +bin = stereoview
     1.7 +
     1.8 +CXX = g++
     1.9 +CXXFLAGS = -pedantic -Wall -g `pkg-config --cflags henge2`
    1.10 +LDFLAGS = `pkg-config --libs henge2` $(libgl)
    1.11 +
    1.12 +ifneq ($(shell uname -s), Darwin)
    1.13 +	libgl = -lGL -lGLU -lglut
    1.14 +else
    1.15 +	libgl = -framework OpenGL -framework GLUT
    1.16 +endif
    1.17 +
    1.18 +$(bin): $(obj)
    1.19 +	$(CXX) -o $@ $(obj) $(LDFLAGS)
    1.20 +
    1.21 +.PHONY: clean
    1.22 +clean:
    1.23 +	rm -f $(obj) $(bin)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/cam.cc	Fri Mar 04 06:51:16 2011 +0200
     2.3 @@ -0,0 +1,162 @@
     2.4 +#include <henge.h>
     2.5 +#include "cam.h"
     2.6 +
     2.7 +/* viewing parameters */
     2.8 +#define DEF_THETA	0
     2.9 +#define DEF_PHI		25
    2.10 +#define DEF_DIST	5
    2.11 +#define DEF_X		0
    2.12 +#define DEF_Y		0.25
    2.13 +#define DEF_Z		0
    2.14 +
    2.15 +static float cam_theta = DEF_THETA, cam_phi = DEF_PHI;
    2.16 +static float cam_dist = DEF_DIST;
    2.17 +static Vector3 cam_pos(DEF_X, DEF_Y, DEF_Z);
    2.18 +
    2.19 +/* projection parameters */
    2.20 +#define DEF_VFOV	45.0
    2.21 +#define DEF_ASPECT	1.3333333
    2.22 +#define DEF_NEAR	1.0
    2.23 +#define DEF_FAR		1000.0
    2.24 +
    2.25 +static float vfov = DEF_VFOV;
    2.26 +static float aspect = DEF_ASPECT;
    2.27 +static float nearclip = DEF_NEAR, farclip = DEF_FAR;
    2.28 +
    2.29 +/* stereo parameters */
    2.30 +#define DEF_EYE_SEP		0.1
    2.31 +#define DEF_FOCUS_DIST	1.0
    2.32 +
    2.33 +static float eye_sep = DEF_EYE_SEP;
    2.34 +static float focus_dist = DEF_FOCUS_DIST;
    2.35 +
    2.36 +
    2.37 +static float rot_speed = 0.5;
    2.38 +static float zoom_speed = 0.1;
    2.39 +
    2.40 +static float cam_speed = 1.0;
    2.41 +
    2.42 +
    2.43 +void cam_reset(void)
    2.44 +{
    2.45 +	cam_reset_view();
    2.46 +	cam_reset_proj();
    2.47 +	cam_reset_stereo();
    2.48 +}
    2.49 +
    2.50 +void cam_reset_view(void)
    2.51 +{
    2.52 +	cam_theta = DEF_THETA;
    2.53 +	cam_phi = DEF_PHI;
    2.54 +	cam_dist = DEF_DIST;
    2.55 +	cam_pos = Vector3(DEF_X, DEF_Y, DEF_Z);
    2.56 +}
    2.57 +
    2.58 +void cam_reset_proj(void)
    2.59 +{
    2.60 +	vfov = DEF_VFOV;
    2.61 +	aspect = DEF_ASPECT;
    2.62 +	nearclip = DEF_NEAR;
    2.63 +	farclip = DEF_FAR;
    2.64 +}
    2.65 +
    2.66 +void cam_reset_stereo(void)
    2.67 +{
    2.68 +	eye_sep = DEF_EYE_SEP;
    2.69 +	focus_dist = DEF_FOCUS_DIST;
    2.70 +}
    2.71 +
    2.72 +void cam_pan(int dx, int dy)
    2.73 +{
    2.74 +	float dxf = dx * cam_speed;// * cam_dist;
    2.75 +	float dyf = dy * cam_speed;// * cam_dist;
    2.76 +	float angle = -DEG_TO_RAD(cam_theta);
    2.77 +
    2.78 +	cam_pos.x += cos(angle) * dxf + sin(angle) * dyf;
    2.79 +	cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf;
    2.80 +}
    2.81 +
    2.82 +void cam_height(int dh)
    2.83 +{
    2.84 +	cam_pos.y += dh * cam_speed;// * cam_dist;
    2.85 +}
    2.86 +
    2.87 +void cam_rotate(int dx, int dy)
    2.88 +{
    2.89 +	cam_theta += dx * rot_speed;
    2.90 +	cam_phi += dy * rot_speed;
    2.91 +
    2.92 +	if(cam_phi < -90) cam_phi = -90;
    2.93 +	if(cam_phi > 90) cam_phi = 90;
    2.94 +}
    2.95 +
    2.96 +void cam_zoom(int dz)
    2.97 +{
    2.98 +	cam_dist += dz * zoom_speed;
    2.99 +	if(cam_dist < 0.001) {
   2.100 +		cam_dist = 0.001;
   2.101 +	}
   2.102 +}
   2.103 +
   2.104 +void cam_clip(float n, float f)
   2.105 +{
   2.106 +	nearclip = n;
   2.107 +	farclip = f;
   2.108 +}
   2.109 +
   2.110 +void cam_fov(float f)
   2.111 +{
   2.112 +	vfov = f;
   2.113 +}
   2.114 +
   2.115 +void cam_aspect(float a)
   2.116 +{
   2.117 +	aspect = a;
   2.118 +}
   2.119 +
   2.120 +void cam_separation(float s)
   2.121 +{
   2.122 +	eye_sep = s;
   2.123 +}
   2.124 +
   2.125 +void cam_focus_dist(float d)
   2.126 +{
   2.127 +	focus_dist = d;
   2.128 +
   2.129 +	cam_separation(d / 30.0);
   2.130 +}
   2.131 +
   2.132 +void cam_view_matrix(void)
   2.133 +{
   2.134 +	cam_stereo_view_matrix(CAM_CENTER);
   2.135 +}
   2.136 +
   2.137 +void cam_stereo_view_matrix(int eye)
   2.138 +{
   2.139 +	static const float offs_sign[] = {0.0f, 0.5f, -0.5f};	/* center, left, right */
   2.140 +	float offs = eye_sep * offs_sign[eye];
   2.141 +
   2.142 +	glTranslatef(offs, 0, 0);
   2.143 +
   2.144 +	glTranslatef(0, 0, -cam_dist);
   2.145 +	glRotatef(cam_phi, 1, 0, 0);
   2.146 +	glRotatef(cam_theta, 0, 1, 0);
   2.147 +	glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
   2.148 +}
   2.149 +
   2.150 +void cam_proj_matrix(void)
   2.151 +{
   2.152 +	cam_stereo_proj_matrix(CAM_CENTER);
   2.153 +}
   2.154 +
   2.155 +void cam_stereo_proj_matrix(int eye)
   2.156 +{
   2.157 +	float vfov_rad = M_PI * vfov / 180.0;
   2.158 +	float top = nearclip * tan(vfov_rad * 0.5);
   2.159 +	float right = top * aspect;
   2.160 +
   2.161 +	static const float offs_sign[] = {0.0f, 1.0, -1.0};	/* center, left, right */
   2.162 +	float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist);
   2.163 +
   2.164 +	glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip);
   2.165 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/cam.h	Fri Mar 04 06:51:16 2011 +0200
     3.3 @@ -0,0 +1,43 @@
     3.4 +#ifndef CAM_H_
     3.5 +#define CAM_H_
     3.6 +
     3.7 +enum {
     3.8 +	CAM_CENTER,
     3.9 +	CAM_LEFT,
    3.10 +	CAM_RIGHT
    3.11 +};
    3.12 +
    3.13 +/* reset to the initial state */
    3.14 +void cam_reset(void);			/* all */
    3.15 +void cam_reset_view(void);		/* view parameters */
    3.16 +void cam_reset_proj(void);		/* projection parameters */
    3.17 +void cam_reset_stereo(void);	/* stereo parameters */
    3.18 +
    3.19 +/* camera viewing parameters */
    3.20 +void cam_pan(int dx, int dy);		/* pan across X/Z plane */
    3.21 +void cam_height(int dh);			/* move verticaly */
    3.22 +void cam_rotate(int dx, int dy);	/* rotate around local Y and X axis */
    3.23 +void cam_zoom(int dz);				/* dolly the camera fwd/back */
    3.24 +
    3.25 +/* camera projection parameters */
    3.26 +void cam_clip(float n, float f);	/* set clipping planes */
    3.27 +void cam_fov(float f);				/* vertical field of view in degrees */
    3.28 +void cam_aspect(float a);			/* aspect ratio (width / height) */
    3.29 +
    3.30 +/* stereo parameters */
    3.31 +void cam_separation(float s);
    3.32 +void cam_focus_dist(float d);
    3.33 +
    3.34 +/* multiply the camera view matrix on top of the current matrix stack
    3.35 + * (which should be GL_MODELVIEW)
    3.36 + */
    3.37 +void cam_view_matrix(void);
    3.38 +void cam_stereo_view_matrix(int eye);
    3.39 +
    3.40 +/* multiply the camera projection matrix on top of the current matrix stack
    3.41 + * (which should be GL_PROJECTION)
    3.42 + */
    3.43 +void cam_proj_matrix(void);
    3.44 +void cam_stereo_proj_matrix(int eye);
    3.45 +
    3.46 +#endif	/* CAM_H_ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/stereoview.cc	Fri Mar 04 06:51:16 2011 +0200
     4.3 @@ -0,0 +1,268 @@
     4.4 +#include <stdio.h>
     4.5 +#include <stdlib.h>
     4.6 +#include <assert.h>
     4.7 +#include <henge.h>
     4.8 +
     4.9 +#ifndef __APPLE__
    4.10 +#include <GL/glut.h>
    4.11 +#else
    4.12 +#include <GLUT/glut.h>
    4.13 +#endif
    4.14 +
    4.15 +#include "cam.h"
    4.16 +#include "zscn.h"
    4.17 +
    4.18 +struct Light {
    4.19 +	float pos[4];
    4.20 +	float color[4];
    4.21 +};
    4.22 +
    4.23 +static void cleanup();
    4.24 +static int parse_args(int argc, char **argv);
    4.25 +static void disp();
    4.26 +static void render_scene();
    4.27 +static void reshape(int x, int y);
    4.28 +static void keyb(unsigned char key, int x, int y);
    4.29 +static void mouse(int bn, int state, int x, int y);
    4.30 +static void motion(int x, int y);
    4.31 +
    4.32 +static bool use_stereo = false;
    4.33 +static bool use_zbuf = true;
    4.34 +
    4.35 +static std::list<std::string> scn_fnames;
    4.36 +static henge::Scene *scn;
    4.37 +
    4.38 +
    4.39 +int main(int argc, char **argv)
    4.40 +{
    4.41 +	unsigned int init_flags = GLUT_RGB | GLUT_DOUBLE;
    4.42 +
    4.43 +	atexit(cleanup);
    4.44 +
    4.45 +	glutInitWindowSize(800, 600);
    4.46 +	glutInit(&argc, argv);
    4.47 +
    4.48 +	if(parse_args(argc, argv) == -1) {
    4.49 +		return 1;
    4.50 +	}
    4.51 +	if(use_stereo) {
    4.52 +		init_flags |= GLUT_STEREO;
    4.53 +	}
    4.54 +	if(use_zbuf) {
    4.55 +		init_flags |= GLUT_DEPTH;
    4.56 +	}
    4.57 +
    4.58 +	glutInitDisplayMode(init_flags);
    4.59 +	glutCreateWindow("stereoscopic scene viewer");
    4.60 +
    4.61 +	glutDisplayFunc(disp);
    4.62 +	glutReshapeFunc(reshape);
    4.63 +	glutKeyboardFunc(keyb);
    4.64 +	glutMouseFunc(mouse);
    4.65 +	glutMotionFunc(motion);
    4.66 +
    4.67 +	if(use_zbuf) {
    4.68 +		glEnable(GL_DEPTH_TEST);
    4.69 +	}
    4.70 +
    4.71 +	glEnable(GL_LIGHTING);
    4.72 +	{
    4.73 +		int i, num_lights;
    4.74 +		struct Light lights[] = {
    4.75 +			{{-0.85, 0.7, 1, 0}, {1.0, 1.0, 1.0, 1.0}},
    4.76 +			{{1, -0.5, 0.9, 0}, {0.75, 0.75, 0.75, 1.0}},
    4.77 +			{{0, 0, 1, 0}, {0.4, 0.4, 0.4, 1.0}}
    4.78 +		};
    4.79 +
    4.80 +		num_lights = sizeof lights / sizeof *lights;
    4.81 +
    4.82 +		for(i=0; i<num_lights; i++) {
    4.83 +			GLenum id = GL_LIGHT0 + i;
    4.84 +			glLightfv(id, GL_POSITION, lights[i].pos);
    4.85 +			glLightfv(id, GL_DIFFUSE, lights[i].color);
    4.86 +			glLightfv(id, GL_SPECULAR, lights[i].color);
    4.87 +			glEnable(id);
    4.88 +		}
    4.89 +	}
    4.90 +
    4.91 +	glEnable(GL_CULL_FACE);
    4.92 +
    4.93 +	if(!henge::init()) {
    4.94 +		return 1;
    4.95 +	}
    4.96 +
    4.97 +	scn = new ZScene;
    4.98 +
    4.99 +	std::list<std::string>::iterator it = scn_fnames.begin();
   4.100 +	while(it != scn_fnames.end()) {
   4.101 +		if(!(scn->load(it->c_str()))) {
   4.102 +			fprintf(stderr, "failed to load scene: %s\n", it->c_str());
   4.103 +			return 1;
   4.104 +		}
   4.105 +		it++;
   4.106 +	}
   4.107 +	if(!scn->object_count()) {
   4.108 +		fprintf(stderr, "didn't load any geometry, aborting\n");
   4.109 +		return 1;
   4.110 +	}
   4.111 +
   4.112 +	henge::Renderer *rend = henge::get_renderer();
   4.113 +	rend->set_render_mask(henge::REND_ALL & ~henge::REND_CAM);
   4.114 +
   4.115 +	cam_reset();
   4.116 +
   4.117 +	glutMainLoop();
   4.118 +	return 0;
   4.119 +}
   4.120 +
   4.121 +static void cleanup()
   4.122 +{
   4.123 +	delete scn;
   4.124 +}
   4.125 +
   4.126 +static int parse_args(int argc, char **argv)
   4.127 +{
   4.128 +	for(int i=1; i<argc; i++) {
   4.129 +		if(argv[i][0] == '-') {
   4.130 +			if(argv[i][2]) {
   4.131 +				fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
   4.132 +				return -1;
   4.133 +			}
   4.134 +			switch(argv[i][1]) {
   4.135 +			case 's':
   4.136 +				use_stereo = true;
   4.137 +				break;
   4.138 +
   4.139 +			case 'd':
   4.140 +			case 'z':
   4.141 +				use_zbuf = false;
   4.142 +				break;
   4.143 +
   4.144 +			case 'h':
   4.145 +				printf("usage: %s [options]\n", argv[0]);
   4.146 +				printf(" -s\tuse stereoscopic rendering\n");
   4.147 +				printf(" -h\tprint usage and exit\n");
   4.148 +				exit(0);
   4.149 +
   4.150 +			default:
   4.151 +				fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
   4.152 +				return -1;
   4.153 +			}
   4.154 +		} else {
   4.155 +			scn_fnames.push_back(argv[i]);
   4.156 +		}
   4.157 +	}
   4.158 +
   4.159 +	return 0;
   4.160 +}
   4.161 +
   4.162 +static void disp()
   4.163 +{
   4.164 +	unsigned int clear_flags = GL_COLOR_BUFFER_BIT | (use_zbuf ? GL_DEPTH_BUFFER_BIT : 0);
   4.165 +
   4.166 +	glMatrixMode(GL_PROJECTION);
   4.167 +	glLoadIdentity();
   4.168 +	cam_stereo_proj_matrix(use_stereo ? CAM_LEFT : CAM_CENTER);
   4.169 +	glMatrixMode(GL_MODELVIEW);
   4.170 +	glLoadIdentity();
   4.171 +	cam_stereo_view_matrix(use_stereo ? CAM_LEFT : CAM_CENTER);
   4.172 +
   4.173 +	if(!use_stereo) {
   4.174 +		glClear(clear_flags);
   4.175 +		render_scene();
   4.176 +	} else {
   4.177 +		glDrawBuffer(GL_BACK_LEFT);
   4.178 +		glClear(clear_flags);
   4.179 +		render_scene();
   4.180 +
   4.181 +		glMatrixMode(GL_PROJECTION);
   4.182 +		glLoadIdentity();
   4.183 +		cam_stereo_proj_matrix(CAM_RIGHT);
   4.184 +		glMatrixMode(GL_MODELVIEW);
   4.185 +		glLoadIdentity();
   4.186 +		cam_stereo_view_matrix(CAM_RIGHT);
   4.187 +
   4.188 +		glDrawBuffer(GL_BACK_RIGHT);
   4.189 +		glClear(clear_flags);
   4.190 +		render_scene();
   4.191 +	}
   4.192 +
   4.193 +	glutSwapBuffers();
   4.194 +	assert(glGetError() == GL_NO_ERROR);
   4.195 +}
   4.196 +
   4.197 +static void render_scene()
   4.198 +{
   4.199 +	scn->render();
   4.200 +}
   4.201 +
   4.202 +static void reshape(int x, int y)
   4.203 +{
   4.204 +	glViewport(0, 0, x, y);
   4.205 +
   4.206 +	cam_aspect((float)x / (float)y);
   4.207 +}
   4.208 +
   4.209 +static void keyb(unsigned char key, int x, int y)
   4.210 +{
   4.211 +	static float focus_dist = 1.0;
   4.212 +
   4.213 +	switch(key) {
   4.214 +	case 27:
   4.215 +		exit(0);
   4.216 +
   4.217 +	case '-':
   4.218 +		focus_dist -= 0.5;
   4.219 +		cam_focus_dist(focus_dist);
   4.220 +		glutPostRedisplay();
   4.221 +		printf("focus_dist: %f\n", focus_dist);
   4.222 +		break;
   4.223 +
   4.224 +	case '=':
   4.225 +		focus_dist += 0.5;
   4.226 +		cam_focus_dist(focus_dist);
   4.227 +		glutPostRedisplay();
   4.228 +		printf("focus_dist: %f\n", focus_dist);
   4.229 +		break;
   4.230 +
   4.231 +	default:
   4.232 +		break;
   4.233 +	}
   4.234 +}
   4.235 +
   4.236 +static int px = -1, py;
   4.237 +static int bnstate[32];
   4.238 +
   4.239 +static void mouse(int bn, int state, int x, int y)
   4.240 +{
   4.241 +	bnstate[bn] = state == GLUT_DOWN ? 1 : 0;
   4.242 +
   4.243 +	if(state == GLUT_DOWN) {
   4.244 +		px = x;
   4.245 +		py = y;
   4.246 +	} else {
   4.247 +		px = -1;
   4.248 +	}
   4.249 +}
   4.250 +
   4.251 +static void motion(int x, int y)
   4.252 +{
   4.253 +	int dx = x - px;
   4.254 +	int dy = y - py;
   4.255 +
   4.256 +	px = x;
   4.257 +	py = y;
   4.258 +
   4.259 +	if(bnstate[0]) {
   4.260 +		cam_rotate(dx, dy);
   4.261 +		glutPostRedisplay();
   4.262 +	}
   4.263 +	if(bnstate[1]) {
   4.264 +		cam_pan(dx, dy);
   4.265 +		glutPostRedisplay();
   4.266 +	}
   4.267 +	if(bnstate[2]) {
   4.268 +		cam_zoom(dy);
   4.269 +		glutPostRedisplay();
   4.270 +	}
   4.271 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/zscn.cc	Fri Mar 04 06:51:16 2011 +0200
     5.3 @@ -0,0 +1,127 @@
     5.4 +#include <list>
     5.5 +#include "zscn.h"
     5.6 +
     5.7 +struct Face {
     5.8 +	Vector3 v[3];
     5.9 +	Vector3 n[3];
    5.10 +	Vector2 t[3];
    5.11 +
    5.12 +	const henge::Material *mat;
    5.13 +
    5.14 +	Face()
    5.15 +	{
    5.16 +		memset(this, 0, sizeof(Face));
    5.17 +	}
    5.18 +};
    5.19 +
    5.20 +static void proc_mesh(std::list<Face> *facelist, const henge::TriMesh *mesh,
    5.21 +		const henge::Material *mat, const Matrix4x4 &xform);
    5.22 +static bool operator <(const Face &a, const Face &b);
    5.23 +
    5.24 +ZScene::~ZScene()
    5.25 +{
    5.26 +}
    5.27 +
    5.28 +void ZScene::render(unsigned int msec) const
    5.29 +{
    5.30 +	setup_lights(msec);
    5.31 +
    5.32 +	glMatrixMode(GL_MODELVIEW);
    5.33 +
    5.34 +	Matrix4x4 view_mat;
    5.35 +	henge::store_matrix(&view_mat);
    5.36 +
    5.37 +	std::list<Face> facelist;
    5.38 +
    5.39 +	for(size_t i=0; i<objects.size(); i++) {
    5.40 +		const henge::RObject *obj = objects[i];
    5.41 +		Matrix4x4 xform = obj->get_xform_matrix(msec) * view_mat;
    5.42 +
    5.43 +		const henge::Material *mat = ((henge::RObject*)obj)->get_material_ptr();
    5.44 +		const henge::TriMesh *mesh = obj->get_mesh();
    5.45 +
    5.46 +		proc_mesh(&facelist, mesh, mat, xform);
    5.47 +	}
    5.48 +
    5.49 +	facelist.sort();
    5.50 +
    5.51 +	glPushAttrib(GL_ENABLE_BIT);
    5.52 +	glDisable(GL_DEPTH_TEST);
    5.53 +
    5.54 +	glPushMatrix();
    5.55 +	glLoadIdentity();
    5.56 +
    5.57 +	glBegin(GL_TRIANGLES);
    5.58 +
    5.59 +	const henge::Material *cur_mat = 0;
    5.60 +	std::list<Face>::iterator face = facelist.begin();
    5.61 +	while(face != facelist.end()) {
    5.62 +		if(face->mat != cur_mat) {
    5.63 +			glEnd();
    5.64 +
    5.65 +			face->mat->bind();
    5.66 +			cur_mat = face->mat;
    5.67 +
    5.68 +			glBegin(GL_TRIANGLES);
    5.69 +		}
    5.70 +
    5.71 +		for(int i=0; i<3; i++) {
    5.72 +			glNormal3f(face->n[i].x, face->n[i].y, face->n[i].z);
    5.73 +			glTexCoord2f(face->t[i].x, face->t[i].y);
    5.74 +			glVertex3f(face->v[i].x, face->v[i].y, face->v[i].z);
    5.75 +		}
    5.76 +
    5.77 +		face++;
    5.78 +	}
    5.79 +	glEnd();
    5.80 +
    5.81 +	glMatrixMode(GL_MODELVIEW);
    5.82 +	glPopMatrix();
    5.83 +	glPopAttrib();
    5.84 +}
    5.85 +
    5.86 +static void proc_mesh(std::list<Face> *facelist, const henge::TriMesh *mesh,
    5.87 +		const henge::Material *mat, const Matrix4x4 &xform)
    5.88 +{
    5.89 +	Matrix3x3 norm_xform = xform;
    5.90 +
    5.91 +	const Vector3 *vert = mesh->get_data_vec3(henge::EL_VERTEX);
    5.92 +	const Vector3 *norm = mesh->get_data_vec3(henge::EL_NORMAL);
    5.93 +	const Vector2 *tc = mesh->get_data_vec2(henge::EL_TEXCOORD);
    5.94 +	const unsigned int *index = mesh->get_data_int(henge::EL_INDEX);
    5.95 +
    5.96 +	int nvert = mesh->get_count(henge::EL_VERTEX);
    5.97 +	int nindex = mesh->get_count(henge::EL_INDEX);
    5.98 +
    5.99 +	if(!vert || !nvert) {
   5.100 +		return;
   5.101 +	}
   5.102 +
   5.103 +	int face_count = (index ? nindex : nvert) / 3;
   5.104 +
   5.105 +	for(int i=0; i<face_count; i++) {
   5.106 +		Face face;
   5.107 +
   5.108 +		for(int j=0; j<3; j++) {
   5.109 +			int idx = index ? index[i * 3 + j] : i * 3 + j;
   5.110 +
   5.111 +			if(norm) {
   5.112 +				face.n[j] = norm[idx].transformed(norm_xform);
   5.113 +			}
   5.114 +			if(tc) {
   5.115 +				face.t[j] = tc[idx];
   5.116 +			}
   5.117 +			if(vert) {
   5.118 +				face.v[j] = vert[idx].transformed(xform);
   5.119 +			}
   5.120 +		}
   5.121 +
   5.122 +		face.mat = mat;
   5.123 +		facelist->push_back(face);
   5.124 +	}
   5.125 +}
   5.126 +
   5.127 +static bool operator <(const Face &a, const Face &b)
   5.128 +{
   5.129 +	return (a.v[0].z + a.v[1].z + a.v[2].z) < (b.v[0].z + b.v[1].z + b.v[2].z);
   5.130 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/zscn.h	Fri Mar 04 06:51:16 2011 +0200
     6.3 @@ -0,0 +1,8 @@
     6.4 +#include <henge.h>
     6.5 +
     6.6 +class ZScene : public henge::Scene {
     6.7 +public:
     6.8 +	virtual ~ZScene();
     6.9 +
    6.10 +	virtual void render(unsigned int msec = 0) const;
    6.11 +};