metasurf

changeset 0:7aa4627e492b

first commit
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 25 Oct 2011 07:34:31 +0300
parents
children dc0e882ec3f9
files .hgignore Makefile.in configure examples/metaballs/Makefile examples/metaballs/sdr/frag.glsl examples/metaballs/sdr/vert.glsl examples/metaballs/src/cam.c examples/metaballs/src/cam.h examples/metaballs/src/sdr.c examples/metaballs/src/sdr.h examples/metaballs/src/test.c src/mcubes.h src/metasurf.c src/metasurf.h
diffstat 14 files changed, 1816 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Tue Oct 25 07:34:31 2011 +0300
     1.3 @@ -0,0 +1,7 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     1.7 +^libmetasurf\.so
     1.8 +^libmetasurf\.a$
     1.9 +^metasurf\.dylib
    1.10 +^Makefile$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile.in	Tue Oct 25 07:34:31 2011 +0300
     2.3 @@ -0,0 +1,65 @@
     2.4 +src = $(wildcard src/*.c)
     2.5 +obj = $(src:.c=.o)
     2.6 +dep = $(obj:.o=.d)
     2.7 +
     2.8 +hdr = metasurf.h
     2.9 +
    2.10 +name = metasurf
    2.11 +lib_a = lib$(name).a
    2.12 +somajor = 0
    2.13 +sominor = 1
    2.14 +
    2.15 +ifeq ($(shell uname -s), Darwin)
    2.16 +	lib_so = $(name).dylib
    2.17 +	shared = -dynamiclib
    2.18 +else
    2.19 +	devlink = lib$(name).so
    2.20 +	soname = $(devlink).$(somajor)
    2.21 +	lib_so = $(soname).$(sominor)
    2.22 +	shared = -shared -Wl,-soname=$(soname)
    2.23 +	pic = -fPIC
    2.24 +endif
    2.25 +
    2.26 +CC = gcc
    2.27 +AR = ar
    2.28 +CFLAGS = -pedantic -Wall $(dbg) $(opt) $(pic)
    2.29 +
    2.30 +.PHONY: all
    2.31 +all: $(lib_so) $(lib_a)
    2.32 +
    2.33 +$(lib_so): $(obj)
    2.34 +	$(CC) -o $@ $(shared) $(LDFLAGS)
    2.35 +
    2.36 +$(lib_a): $(obj)
    2.37 +	$(AR) rcs $@ $(obj)
    2.38 +
    2.39 +-include $(dep)
    2.40 +
    2.41 +%.d: %.c
    2.42 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    2.43 +
    2.44 +.PHONY: clean
    2.45 +clean:
    2.46 +	rm -f $(obj) $(lib_a) $(lib_so) $(dep)
    2.47 +
    2.48 +.PHONY: cleandep
    2.49 +cleandep:
    2.50 +	rm -f $(dep)
    2.51 +
    2.52 +.PHONY: install
    2.53 +install:
    2.54 +	mkdir -p $(PREFIX)/include $(PREFIX)/lib
    2.55 +	cp src/$(hdr) $(PREFIX)/include/$(hdr)
    2.56 +	cp $(lib_so) $(PREFIX)/lib/$(lib_so)
    2.57 +	[ -n "$(soname)" ] \
    2.58 +		&& ln -s $(PREFIX)/lib/$(lib_so) $(PREFIX)/lib/$(soname) \
    2.59 +		&& ln -s $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \
    2.60 +		|| true
    2.61 +
    2.62 +.PHONY: uninstall
    2.63 +uninstall:
    2.64 +	rm -f $(PREFIX)/include/$(hdr)
    2.65 +	rm -f $(PREFIX)/lib/$(lib_so)
    2.66 +	[ -n "$(soname)" ] \
    2.67 +		&& rm -f $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \
    2.68 +		|| true
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/configure	Tue Oct 25 07:34:31 2011 +0300
     3.3 @@ -0,0 +1,42 @@
     3.4 +#!/bin/sh
     3.5 +
     3.6 +prefix=/usr/local
     3.7 +opt=true
     3.8 +dbg=true
     3.9 +
    3.10 +while [ $# -ne 0 ]; do
    3.11 +	case "$1" in
    3.12 +	--prefix=*)
    3.13 +		prefix=`echo $1 | sed 's/--prefix=//'`
    3.14 +		;;
    3.15 +
    3.16 +	--enable-debug)
    3.17 +		dbg=true
    3.18 +		;;
    3.19 +	--disable-debug)
    3.20 +		dbg=false
    3.21 +		;;
    3.22 +	--enable-opt)
    3.23 +		opt=true
    3.24 +		;;
    3.25 +	--disable-opt)
    3.26 +		opt=false
    3.27 +		;;
    3.28 +	esac
    3.29 +	shift
    3.30 +done
    3.31 +
    3.32 +
    3.33 +echo 'configuring metasurf...'
    3.34 +echo "           prefix: $prefix"
    3.35 +echo 'debugging symbols:' `$dbg && echo yes || echo no`
    3.36 +echo '     optimization:' `$opt && echo yes || echo no`
    3.37 +
    3.38 +echo 'generating makefile...'
    3.39 +echo "# automatically generated by the configure script" >Makefile
    3.40 +echo "PREFIX = $prefix" >>Makefile
    3.41 +$opt && echo "opt = -O3" >>Makefile
    3.42 +$dbg && echo "dbg = -g" >>Makefile
    3.43 +cat Makefile.in >>Makefile
    3.44 +
    3.45 +echo done.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/examples/metaballs/Makefile	Tue Oct 25 07:34:31 2011 +0300
     4.3 @@ -0,0 +1,31 @@
     4.4 +src = $(wildcard src/*.c)
     4.5 +obj = $(src:.c=.o)
     4.6 +dep = $(obj:.o=.d)
     4.7 +bin = metasurf
     4.8 +
     4.9 +CC = gcc
    4.10 +CFLAGS = -pedantic -Wall -g -O3
    4.11 +LDFLAGS = $(libgl)
    4.12 +
    4.13 +ifeq ($(shell uname -s), Darwin)
    4.14 +	libgl = -framework OpenGL -framework GLUT -lGLEW
    4.15 +else
    4.16 +	libgl = -lGL -lGLU -lglut -lGLEW
    4.17 +endif
    4.18 +
    4.19 +$(bin): $(obj)
    4.20 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    4.21 +
    4.22 +-include $(dep)
    4.23 +
    4.24 +%.d: %.c
    4.25 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    4.26 +
    4.27 +.PHONY: clean
    4.28 +clean:
    4.29 +	rm -f $(obj) $(bin)
    4.30 +
    4.31 +
    4.32 +.PHONY: cleandep
    4.33 +cleandep:
    4.34 +	rm -f $(dep)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/examples/metaballs/sdr/frag.glsl	Tue Oct 25 07:34:31 2011 +0300
     5.3 @@ -0,0 +1,19 @@
     5.4 +varying vec3 vpos, ldir, norm;
     5.5 +
     5.6 +void main()
     5.7 +{
     5.8 +	vec3 n = normalize(norm);
     5.9 +	vec3 l = normalize(ldir);
    5.10 +	vec3 v = -normalize(vpos);
    5.11 +	vec3 h = normalize(v + l);
    5.12 +
    5.13 +	const vec3 kd = vec3(0.42, 0.6, 0.43);
    5.14 +
    5.15 +	float diff = abs(dot(n, l));
    5.16 +	float spec = pow(abs(dot(n, h)), 60.0);
    5.17 +
    5.18 +	vec3 dcol = kd * diff;
    5.19 +	vec3 scol = vec3(0.8, 0.8, 0.8) * spec;
    5.20 +
    5.21 +	gl_FragColor = vec4(dcol + scol, 1.0);
    5.22 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/examples/metaballs/sdr/vert.glsl	Tue Oct 25 07:34:31 2011 +0300
     6.3 @@ -0,0 +1,10 @@
     6.4 +varying vec3 vpos, ldir, norm;
     6.5 +
     6.6 +void main()
     6.7 +{
     6.8 +	gl_Position = ftransform();
     6.9 +
    6.10 +	vpos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    6.11 +	norm = gl_NormalMatrix * gl_Normal;
    6.12 +	ldir = gl_LightSource[0].position.xyz;
    6.13 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/examples/metaballs/src/cam.c	Tue Oct 25 07:34:31 2011 +0300
     7.3 @@ -0,0 +1,216 @@
     7.4 +#include <math.h>
     7.5 +#include "cam.h"
     7.6 +
     7.7 +#if defined(__APPLE__) && defined(__MACH__)
     7.8 +#include <OpenGL/gl.h>
     7.9 +#else
    7.10 +#include <GL/gl.h>
    7.11 +#endif
    7.12 +
    7.13 +#define DR				(M_PI / 180.0)
    7.14 +#define DEG_TO_RAD(x)	((x) * DR)
    7.15 +
    7.16 +typedef struct vec3 {
    7.17 +	float x, y, z;
    7.18 +} vec3_t;
    7.19 +
    7.20 +/* viewing parameters */
    7.21 +#define DEF_THETA	0
    7.22 +#define DEF_PHI		0
    7.23 +#define DEF_DIST	0
    7.24 +#define DEF_X		0
    7.25 +#define DEF_Y		0
    7.26 +#define DEF_Z		0
    7.27 +
    7.28 +static float cam_theta = DEF_THETA, cam_phi = DEF_PHI;
    7.29 +static float cam_dist = DEF_DIST;
    7.30 +static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z};
    7.31 +
    7.32 +/* projection parameters */
    7.33 +#define DEF_VFOV	45.0
    7.34 +#define DEF_ASPECT	1.3333333
    7.35 +#define DEF_NEAR	1.0
    7.36 +#define DEF_FAR		1000.0
    7.37 +
    7.38 +static float vfov = DEF_VFOV;
    7.39 +static float aspect = DEF_ASPECT;
    7.40 +static float nearclip = DEF_NEAR, farclip = DEF_FAR;
    7.41 +
    7.42 +/* stereo parameters */
    7.43 +#define DEF_EYE_SEP		0.1
    7.44 +#define DEF_FOCUS_DIST	1.0
    7.45 +
    7.46 +static float eye_sep = DEF_EYE_SEP;
    7.47 +static float focus_dist = DEF_FOCUS_DIST;
    7.48 +
    7.49 +static float pan_speed = 0.001;
    7.50 +static float rot_speed = 0.5;
    7.51 +static float zoom_speed = 0.1;
    7.52 +
    7.53 +static float vmin_deg = -90.0, vmax_deg = 90.0;
    7.54 +
    7.55 +void cam_reset(void)
    7.56 +{
    7.57 +	cam_reset_view();
    7.58 +	cam_reset_proj();
    7.59 +	cam_reset_stereo();
    7.60 +}
    7.61 +
    7.62 +void cam_reset_view(void)
    7.63 +{
    7.64 +	cam_theta = DEF_THETA;
    7.65 +	cam_phi = DEF_PHI;
    7.66 +	cam_dist = DEF_DIST;
    7.67 +	cam_pos.x = DEF_X;
    7.68 +	cam_pos.y = DEF_Y;
    7.69 +	cam_pos.z = DEF_Z;
    7.70 +}
    7.71 +
    7.72 +void cam_reset_proj(void)
    7.73 +{
    7.74 +	vfov = DEF_VFOV;
    7.75 +	aspect = DEF_ASPECT;
    7.76 +	nearclip = DEF_NEAR;
    7.77 +	farclip = DEF_FAR;
    7.78 +}
    7.79 +
    7.80 +void cam_reset_stereo(void)
    7.81 +{
    7.82 +	eye_sep = DEF_EYE_SEP;
    7.83 +	focus_dist = DEF_FOCUS_DIST;
    7.84 +}
    7.85 +
    7.86 +void cam_set_vrange(float min_deg, float max_deg)
    7.87 +{
    7.88 +	vmin_deg = min_deg;
    7.89 +	vmax_deg = max_deg;
    7.90 +}
    7.91 +
    7.92 +void cam_move(float x, float y, float z)
    7.93 +{
    7.94 +	cam_pos.x += x;
    7.95 +	cam_pos.y += y;
    7.96 +	cam_pos.z += z;
    7.97 +}
    7.98 +
    7.99 +void cam_rotate(float theta, float phi)
   7.100 +{
   7.101 +	cam_phi += phi;
   7.102 +	cam_theta += theta;
   7.103 +}
   7.104 +
   7.105 +void cam_dolly(float dist)
   7.106 +{
   7.107 +	cam_dist += dist;
   7.108 +}
   7.109 +
   7.110 +void cam_inp_pan_speed(float speed)
   7.111 +{
   7.112 +	pan_speed = speed;
   7.113 +}
   7.114 +
   7.115 +void cam_inp_rotate_speed(float speed)
   7.116 +{
   7.117 +	rot_speed = speed;
   7.118 +}
   7.119 +
   7.120 +void cam_inp_zoom_speed(float speed)
   7.121 +{
   7.122 +	zoom_speed = speed;
   7.123 +}
   7.124 +
   7.125 +
   7.126 +void cam_inp_pan(int dx, int dy)
   7.127 +{
   7.128 +	float dxf = dx * pan_speed;
   7.129 +	float dyf = dy * pan_speed;
   7.130 +	float angle = -DEG_TO_RAD(cam_theta);
   7.131 +
   7.132 +	cam_pos.x += cos(angle) * dxf + sin(angle) * dyf;
   7.133 +	cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf;
   7.134 +}
   7.135 +
   7.136 +void cam_inp_height(int dh)
   7.137 +{
   7.138 +	cam_pos.y += dh * pan_speed;
   7.139 +}
   7.140 +
   7.141 +void cam_inp_rotate(int dx, int dy)
   7.142 +{
   7.143 +	cam_theta += dx * rot_speed;
   7.144 +	cam_phi += dy * rot_speed;
   7.145 +
   7.146 +	if(cam_phi < vmin_deg) cam_phi = vmin_deg;
   7.147 +	if(cam_phi > vmax_deg) cam_phi = vmax_deg;
   7.148 +}
   7.149 +
   7.150 +void cam_inp_zoom(int dz)
   7.151 +{
   7.152 +	cam_dist += dz * zoom_speed;
   7.153 +	if(cam_dist < 0.001) {
   7.154 +		cam_dist = 0.001;
   7.155 +	}
   7.156 +}
   7.157 +
   7.158 +void cam_clip(float n, float f)
   7.159 +{
   7.160 +	nearclip = n;
   7.161 +	farclip = f;
   7.162 +}
   7.163 +
   7.164 +void cam_fov(float f)
   7.165 +{
   7.166 +	vfov = f;
   7.167 +}
   7.168 +
   7.169 +void cam_aspect(float a)
   7.170 +{
   7.171 +	aspect = a;
   7.172 +}
   7.173 +
   7.174 +void cam_separation(float s)
   7.175 +{
   7.176 +	eye_sep = s;
   7.177 +}
   7.178 +
   7.179 +void cam_focus_dist(float d)
   7.180 +{
   7.181 +	focus_dist = d;
   7.182 +
   7.183 +	cam_separation(d / 30.0);
   7.184 +}
   7.185 +
   7.186 +void cam_view_matrix(void)
   7.187 +{
   7.188 +	cam_stereo_view_matrix(CAM_CENTER);
   7.189 +}
   7.190 +
   7.191 +void cam_stereo_view_matrix(int eye)
   7.192 +{
   7.193 +	static const float offs_sign[] = {0.0f, 0.5f, -0.5f};	/* center, left, right */
   7.194 +	float offs = eye_sep * offs_sign[eye];
   7.195 +
   7.196 +	glTranslatef(offs, 0, 0);
   7.197 +
   7.198 +	glTranslatef(0, 0, -cam_dist);
   7.199 +	glRotatef(cam_phi, 1, 0, 0);
   7.200 +	glRotatef(cam_theta, 0, 1, 0);
   7.201 +	glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
   7.202 +}
   7.203 +
   7.204 +void cam_proj_matrix(void)
   7.205 +{
   7.206 +	cam_stereo_proj_matrix(CAM_CENTER);
   7.207 +}
   7.208 +
   7.209 +void cam_stereo_proj_matrix(int eye)
   7.210 +{
   7.211 +	float vfov_rad = M_PI * vfov / 180.0;
   7.212 +	float top = nearclip * tan(vfov_rad * 0.5);
   7.213 +	float right = top * aspect;
   7.214 +
   7.215 +	static const float offs_sign[] = {0.0f, 1.0, -1.0};	/* center, left, right */
   7.216 +	float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist);
   7.217 +
   7.218 +	glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip);
   7.219 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/examples/metaballs/src/cam.h	Tue Oct 25 07:34:31 2011 +0300
     8.3 @@ -0,0 +1,54 @@
     8.4 +#ifndef CAM_H_
     8.5 +#define CAM_H_
     8.6 +
     8.7 +enum {
     8.8 +	CAM_CENTER,
     8.9 +	CAM_LEFT,
    8.10 +	CAM_RIGHT
    8.11 +};
    8.12 +
    8.13 +/* reset to the initial state */
    8.14 +void cam_reset(void);			/* all */
    8.15 +void cam_reset_view(void);		/* view parameters */
    8.16 +void cam_reset_proj(void);		/* projection parameters */
    8.17 +void cam_reset_stereo(void);	/* stereo parameters */
    8.18 +
    8.19 +void cam_set_vrange(float min_deg, float max_deg);
    8.20 +
    8.21 +void cam_move(float x, float y, float z);
    8.22 +void cam_rotate(float theta, float phi);
    8.23 +void cam_dolly(float dist);
    8.24 +
    8.25 +/* camera input handling */
    8.26 +void cam_inp_pan_speed(float speed);
    8.27 +void cam_inp_rotate_speed(float speed);
    8.28 +void cam_inp_zoom_speed(float speed);
    8.29 +
    8.30 +void cam_inp_pan(int dx, int dy);		/* pan across X/Z plane */
    8.31 +void cam_inp_height(int dh);			/* move verticaly */
    8.32 +void cam_inp_rotate(int dx, int dy);	/* rotate around local Y and X axis */
    8.33 +void cam_inp_zoom(int dz);				/* dolly the camera fwd/back */
    8.34 +
    8.35 +/* camera projection parameters */
    8.36 +void cam_clip(float n, float f);	/* set clipping planes */
    8.37 +void cam_fov(float f);				/* vertical field of view in degrees */
    8.38 +void cam_aspect(float a);			/* aspect ratio (width / height) */
    8.39 +
    8.40 +/* stereo parameters */
    8.41 +void cam_separation(float s);
    8.42 +void cam_focus_dist(float d);
    8.43 +
    8.44 +
    8.45 +/* multiply the camera view matrix on top of the current matrix stack
    8.46 + * (which should be GL_MODELVIEW)
    8.47 + */
    8.48 +void cam_view_matrix(void);
    8.49 +void cam_stereo_view_matrix(int eye);
    8.50 +
    8.51 +/* multiply the camera projection matrix on top of the current matrix stack
    8.52 + * (which should be GL_PROJECTION)
    8.53 + */
    8.54 +void cam_proj_matrix(void);
    8.55 +void cam_stereo_proj_matrix(int eye);
    8.56 +
    8.57 +#endif	/* CAM_H_ */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/examples/metaballs/src/sdr.c	Tue Oct 25 07:34:31 2011 +0300
     9.3 @@ -0,0 +1,329 @@
     9.4 +#include <stdio.h>
     9.5 +#include <stdlib.h>
     9.6 +#include <string.h>
     9.7 +#include <errno.h>
     9.8 +#include <assert.h>
     9.9 +#include <GL/glew.h>
    9.10 +
    9.11 +#if defined(unix) || defined(__unix__)
    9.12 +#include <unistd.h>
    9.13 +#include <sys/stat.h>
    9.14 +#endif	/* unix */
    9.15 +
    9.16 +#include "sdr.h"
    9.17 +
    9.18 +unsigned int create_vertex_shader(const char *src)
    9.19 +{
    9.20 +	return create_shader(src, GL_VERTEX_SHADER);
    9.21 +}
    9.22 +
    9.23 +unsigned int create_pixel_shader(const char *src)
    9.24 +{
    9.25 +	return create_shader(src, GL_FRAGMENT_SHADER);
    9.26 +}
    9.27 +
    9.28 +unsigned int create_shader(const char *src, unsigned int sdr_type)
    9.29 +{
    9.30 +	unsigned int sdr;
    9.31 +	int success, info_len;
    9.32 +	char *info_str = 0;
    9.33 +	GLenum err;
    9.34 +
    9.35 +	sdr = glCreateShader(sdr_type);
    9.36 +	assert(glGetError() == GL_NO_ERROR);
    9.37 +	glShaderSource(sdr, 1, &src, 0);
    9.38 +	err = glGetError();
    9.39 +	assert(err == GL_NO_ERROR);
    9.40 +	glCompileShader(sdr);
    9.41 +	assert(glGetError() == GL_NO_ERROR);
    9.42 +
    9.43 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
    9.44 +	assert(glGetError() == GL_NO_ERROR);
    9.45 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
    9.46 +	assert(glGetError() == GL_NO_ERROR);
    9.47 +
    9.48 +	if(info_len) {
    9.49 +		if((info_str = malloc(info_len + 1))) {
    9.50 +			glGetShaderInfoLog(sdr, info_len, 0, info_str);
    9.51 +			assert(glGetError() == GL_NO_ERROR);
    9.52 +		}
    9.53 +	}
    9.54 +
    9.55 +	if(success) {
    9.56 +		fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
    9.57 +	} else {
    9.58 +		fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
    9.59 +		glDeleteShader(sdr);
    9.60 +		sdr = 0;
    9.61 +	}
    9.62 +
    9.63 +	free(info_str);
    9.64 +	return sdr;
    9.65 +}
    9.66 +
    9.67 +void free_shader(unsigned int sdr)
    9.68 +{
    9.69 +	glDeleteShader(sdr);
    9.70 +}
    9.71 +
    9.72 +unsigned int load_vertex_shader(const char *fname)
    9.73 +{
    9.74 +	return load_shader(fname, GL_VERTEX_SHADER);
    9.75 +}
    9.76 +
    9.77 +unsigned int load_pixel_shader(const char *fname)
    9.78 +{
    9.79 +	return load_shader(fname, GL_FRAGMENT_SHADER);
    9.80 +}
    9.81 +
    9.82 +unsigned int load_shader(const char *fname, unsigned int sdr_type)
    9.83 +{
    9.84 +#if defined(unix) || defined(__unix__)
    9.85 +	struct stat st;
    9.86 +#endif
    9.87 +	unsigned int sdr;
    9.88 +	size_t filesize;
    9.89 +	FILE *fp;
    9.90 +	char *src;
    9.91 +
    9.92 +	if(!(fp = fopen(fname, "r"))) {
    9.93 +		fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
    9.94 +		return 0;
    9.95 +	}
    9.96 +
    9.97 +#if defined(unix) || defined(__unix__)
    9.98 +	fstat(fileno(fp), &st);
    9.99 +	filesize = st.st_size;
   9.100 +#else
   9.101 +	fseek(fp, 0, SEEK_END);
   9.102 +	filesize = ftell(fp);
   9.103 +	fseek(fp, 0, SEEK_SET);
   9.104 +#endif	/* unix */
   9.105 +
   9.106 +	if(!(src = malloc(filesize + 1))) {
   9.107 +		fclose(fp);
   9.108 +		return 0;
   9.109 +	}
   9.110 +	fread(src, 1, filesize, fp);
   9.111 +	src[filesize] = 0;
   9.112 +	fclose(fp);
   9.113 +
   9.114 +	fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname);
   9.115 +	sdr = create_shader(src, sdr_type);
   9.116 +
   9.117 +	free(src);
   9.118 +	return sdr;
   9.119 +}
   9.120 +
   9.121 +
   9.122 +unsigned int get_vertex_shader(const char *fname)
   9.123 +{
   9.124 +	return get_shader(fname, GL_VERTEX_SHADER);
   9.125 +}
   9.126 +
   9.127 +unsigned int get_pixel_shader(const char *fname)
   9.128 +{
   9.129 +	return get_shader(fname, GL_FRAGMENT_SHADER);
   9.130 +}
   9.131 +
   9.132 +unsigned int get_shader(const char *fname, unsigned int sdr_type)
   9.133 +{
   9.134 +	unsigned int sdr;
   9.135 +
   9.136 +	if(!(sdr = load_shader(fname, sdr_type))) {
   9.137 +		return 0;
   9.138 +	}
   9.139 +	return sdr;
   9.140 +}
   9.141 +
   9.142 +
   9.143 +/* ---- gpu programs ---- */
   9.144 +
   9.145 +unsigned int create_program(void)
   9.146 +{
   9.147 +	unsigned int prog = glCreateProgram();
   9.148 +	assert(glGetError() == GL_NO_ERROR);
   9.149 +	return prog;
   9.150 +}
   9.151 +
   9.152 +unsigned int create_program_link(unsigned int vs, unsigned int ps)
   9.153 +{
   9.154 +	unsigned int prog;
   9.155 +
   9.156 +	if(!(prog = create_program())) {
   9.157 +		return 0;
   9.158 +	}
   9.159 +
   9.160 +	if(vs) {
   9.161 +		attach_shader(prog, vs);
   9.162 +		assert(glGetError() == GL_NO_ERROR);
   9.163 +	}
   9.164 +	if(ps) {
   9.165 +		attach_shader(prog, ps);
   9.166 +		assert(glGetError() == GL_NO_ERROR);
   9.167 +	}
   9.168 +
   9.169 +	if(link_program(prog) == -1) {
   9.170 +		free_program(prog);
   9.171 +		return 0;
   9.172 +	}
   9.173 +	return prog;
   9.174 +}
   9.175 +
   9.176 +unsigned int create_program_load(const char *vfile, const char *pfile)
   9.177 +{
   9.178 +	unsigned int vs = 0, ps = 0;
   9.179 +
   9.180 +	if(vfile && !(vs = get_vertex_shader(vfile))) {
   9.181 +		return 0;
   9.182 +	}
   9.183 +	if(pfile && !(ps = get_pixel_shader(pfile))) {
   9.184 +		return 0;
   9.185 +	}
   9.186 +	return create_program_link(vs, ps);
   9.187 +}
   9.188 +
   9.189 +void free_program(unsigned int sdr)
   9.190 +{
   9.191 +	glDeleteProgram(sdr);
   9.192 +}
   9.193 +
   9.194 +void attach_shader(unsigned int prog, unsigned int sdr)
   9.195 +{
   9.196 +	glAttachShader(prog, sdr);
   9.197 +	assert(glGetError() == GL_NO_ERROR);
   9.198 +}
   9.199 +
   9.200 +int link_program(unsigned int prog)
   9.201 +{
   9.202 +	int linked, info_len, retval = 0;
   9.203 +	char *info_str = 0;
   9.204 +
   9.205 +	glLinkProgram(prog);
   9.206 +	assert(glGetError() == GL_NO_ERROR);
   9.207 +	glGetProgramiv(prog, GL_LINK_STATUS, &linked);
   9.208 +	assert(glGetError() == GL_NO_ERROR);
   9.209 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
   9.210 +	assert(glGetError() == GL_NO_ERROR);
   9.211 +
   9.212 +	if(info_len) {
   9.213 +		if((info_str = malloc(info_len + 1))) {
   9.214 +			glGetProgramInfoLog(prog, info_len, 0, info_str);
   9.215 +			assert(glGetError() == GL_NO_ERROR);
   9.216 +		}
   9.217 +	}
   9.218 +
   9.219 +	if(linked) {
   9.220 +		fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
   9.221 +	} else {
   9.222 +		fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
   9.223 +		retval = -1;
   9.224 +	}
   9.225 +
   9.226 +	free(info_str);
   9.227 +	return retval;
   9.228 +}
   9.229 +
   9.230 +int bind_program(unsigned int prog)
   9.231 +{
   9.232 +	GLenum err;
   9.233 +
   9.234 +	glUseProgram(prog);
   9.235 +	if(prog && (err = glGetError()) != GL_NO_ERROR) {
   9.236 +		/* maybe the program is not linked, try linking first */
   9.237 +		if(err == GL_INVALID_OPERATION) {
   9.238 +			if(link_program(prog) == -1) {
   9.239 +				return -1;
   9.240 +			}
   9.241 +			glUseProgram(prog);
   9.242 +			return glGetError() == GL_NO_ERROR ? 0 : -1;
   9.243 +		}
   9.244 +		return -1;
   9.245 +	}
   9.246 +	return 0;
   9.247 +}
   9.248 +
   9.249 +/* ugly but I'm not going to write the same bloody code over and over */
   9.250 +#define BEGIN_UNIFORM_CODE \
   9.251 +	int loc, curr_prog; \
   9.252 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
   9.253 +	if(curr_prog != prog && bind_program(prog) == -1) { \
   9.254 +		return -1; \
   9.255 +	} \
   9.256 +	if((loc = glGetUniformLocation(prog, name)) != -1)
   9.257 +
   9.258 +#define END_UNIFORM_CODE \
   9.259 +	if(curr_prog != prog) { \
   9.260 +		bind_program(curr_prog); \
   9.261 +	} \
   9.262 +	return loc == -1 ? -1 : 0
   9.263 +
   9.264 +int set_uniform_int(unsigned int prog, const char *name, int val)
   9.265 +{
   9.266 +	BEGIN_UNIFORM_CODE {
   9.267 +		glUniform1i(loc, val);
   9.268 +	}
   9.269 +	END_UNIFORM_CODE;
   9.270 +}
   9.271 +
   9.272 +int set_uniform_float(unsigned int prog, const char *name, float val)
   9.273 +{
   9.274 +	BEGIN_UNIFORM_CODE {
   9.275 +		glUniform1f(loc, val);
   9.276 +	}
   9.277 +	END_UNIFORM_CODE;
   9.278 +}
   9.279 +
   9.280 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
   9.281 +{
   9.282 +	BEGIN_UNIFORM_CODE {
   9.283 +		glUniform3f(loc, x, y, z);
   9.284 +	}
   9.285 +	END_UNIFORM_CODE;
   9.286 +}
   9.287 +
   9.288 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
   9.289 +{
   9.290 +	BEGIN_UNIFORM_CODE {
   9.291 +		glUniform4f(loc, x, y, z, w);
   9.292 +	}
   9.293 +	END_UNIFORM_CODE;
   9.294 +}
   9.295 +
   9.296 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat)
   9.297 +{
   9.298 +	BEGIN_UNIFORM_CODE {
   9.299 +		glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
   9.300 +	}
   9.301 +	END_UNIFORM_CODE;
   9.302 +}
   9.303 +
   9.304 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat)
   9.305 +{
   9.306 +	BEGIN_UNIFORM_CODE {
   9.307 +		glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
   9.308 +	}
   9.309 +	END_UNIFORM_CODE;
   9.310 +}
   9.311 +
   9.312 +int get_attrib_loc(unsigned int prog, const char *name)
   9.313 +{
   9.314 +	int loc, curr_prog;
   9.315 +
   9.316 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
   9.317 +	if(curr_prog != prog && bind_program(prog) == -1) {
   9.318 +		return -1;
   9.319 +	}
   9.320 +
   9.321 +	loc = glGetAttribLocation(prog, (char*)name);
   9.322 +
   9.323 +	if(curr_prog != prog) {
   9.324 +		bind_program(curr_prog);
   9.325 +	}
   9.326 +	return loc;
   9.327 +}
   9.328 +
   9.329 +void set_attrib_float3(int attr_loc, float x, float y, float z)
   9.330 +{
   9.331 +	glVertexAttrib3f(attr_loc, x, y, z);
   9.332 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/examples/metaballs/src/sdr.h	Tue Oct 25 07:34:31 2011 +0300
    10.3 @@ -0,0 +1,49 @@
    10.4 +#ifndef SDR_H_
    10.5 +#define SDR_H_
    10.6 +
    10.7 +#ifdef __cplusplus
    10.8 +extern "C" {
    10.9 +#endif	/* __cplusplus */
   10.10 +
   10.11 +/* ---- shaders ---- */
   10.12 +unsigned int create_vertex_shader(const char *src);
   10.13 +unsigned int create_pixel_shader(const char *src);
   10.14 +unsigned int create_shader(const char *src, unsigned int sdr_type);
   10.15 +void free_shader(unsigned int sdr);
   10.16 +
   10.17 +unsigned int load_vertex_shader(const char *fname);
   10.18 +unsigned int load_pixel_shader(const char *fname);
   10.19 +unsigned int load_shader(const char *src, unsigned int sdr_type);
   10.20 +
   10.21 +unsigned int get_vertex_shader(const char *fname);
   10.22 +unsigned int get_pixel_shader(const char *fname);
   10.23 +unsigned int get_shader(const char *fname, unsigned int sdr_type);
   10.24 +
   10.25 +int add_shader(const char *fname, unsigned int sdr);
   10.26 +int remove_shader(const char *fname);
   10.27 +
   10.28 +/* ---- gpu programs ---- */
   10.29 +unsigned int create_program(void);
   10.30 +unsigned int create_program_link(unsigned int vs, unsigned int ps);
   10.31 +unsigned int create_program_load(const char *vfile, const char *pfile);
   10.32 +void free_program(unsigned int sdr);
   10.33 +
   10.34 +void attach_shader(unsigned int prog, unsigned int sdr);
   10.35 +int link_program(unsigned int prog);
   10.36 +int bind_program(unsigned int prog);
   10.37 +
   10.38 +int set_uniform_int(unsigned int prog, const char *name, int val);
   10.39 +int set_uniform_float(unsigned int prog, const char *name, float val);
   10.40 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
   10.41 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
   10.42 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat);
   10.43 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat);
   10.44 +
   10.45 +int get_attrib_loc(unsigned int prog, const char *name);
   10.46 +void set_attrib_float3(int attr_loc, float x, float y, float z);
   10.47 +
   10.48 +#ifdef __cplusplus
   10.49 +}
   10.50 +#endif	/* __cplusplus */
   10.51 +
   10.52 +#endif	/* SDR_H_ */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/examples/metaballs/src/test.c	Tue Oct 25 07:34:31 2011 +0300
    11.3 @@ -0,0 +1,307 @@
    11.4 +#include <stdio.h>
    11.5 +#include <stdlib.h>
    11.6 +#include <math.h>
    11.7 +#include <assert.h>
    11.8 +
    11.9 +#include <GL/glew.h>
   11.10 +#ifndef __APPLE__
   11.11 +#include <GL/glut.h>
   11.12 +#else
   11.13 +#include <GLUT/glut.h>
   11.14 +#endif
   11.15 +
   11.16 +#include "cam.h"
   11.17 +#include "sdr.h"
   11.18 +#include "metasurf.h"
   11.19 +
   11.20 +#define RES		38
   11.21 +
   11.22 +struct metaball {
   11.23 +	float energy;
   11.24 +	float x, y, z;
   11.25 +} mball[] = {
   11.26 +	{1.0, 0, 0, 0},
   11.27 +	{0.25, 0.45, 0, 0.25},
   11.28 +	{0.15, -0.3, 0.2, 0.1}
   11.29 +};
   11.30 +
   11.31 +int num_mballs = sizeof mball / sizeof *mball;
   11.32 +
   11.33 +float eval(float x, float y, float z);
   11.34 +float eval_cached(float x, float y, float z);
   11.35 +void vertex(float x, float y, float z);
   11.36 +void render(void);
   11.37 +void disp(void);
   11.38 +void reshape(int x, int y);
   11.39 +void keyb(unsigned char key, int x, int y);
   11.40 +void mouse(int bn, int state, int x, int y);
   11.41 +void motion(int x, int y);
   11.42 +void sball_button(int bn, int state);
   11.43 +void sball_motion(int x, int y, int z);
   11.44 +int parse_args(int argc, char **argv);
   11.45 +
   11.46 +int stereo;
   11.47 +struct metasurface *msurf;
   11.48 +float threshold = 12;
   11.49 +unsigned int sdr;
   11.50 +int bidx = 1;
   11.51 +
   11.52 +int main(int argc, char **argv)
   11.53 +{
   11.54 +	float amb[] = {0, 0, 0, 0};
   11.55 +	float lpos[] = {-0.2, 0.2, 1, 0};
   11.56 +
   11.57 +	glutInitWindowSize(1280, 720);
   11.58 +	glutInit(&argc, argv);
   11.59 +
   11.60 +	if(parse_args(argc, argv) == -1) {
   11.61 +		return 1;
   11.62 +	}
   11.63 +	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0));
   11.64 +	glutCreateWindow("metasurf");
   11.65 +
   11.66 +	glutDisplayFunc(disp);
   11.67 +	glutReshapeFunc(reshape);
   11.68 +	glutKeyboardFunc(keyb);
   11.69 +	glutMouseFunc(mouse);
   11.70 +	glutMotionFunc(motion);
   11.71 +	glutSpaceballButtonFunc(sball_button);
   11.72 +	glutSpaceballMotionFunc(sball_motion);
   11.73 +
   11.74 +	glewInit();
   11.75 +
   11.76 +	glEnable(GL_CULL_FACE);
   11.77 +	glEnable(GL_DEPTH_TEST);
   11.78 +
   11.79 +	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
   11.80 +
   11.81 +	glEnable(GL_LIGHTING);
   11.82 +	glEnable(GL_LIGHT0);
   11.83 +	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
   11.84 +
   11.85 +	glEnable(GL_NORMALIZE);
   11.86 +
   11.87 +	cam_focus_dist(2.0);
   11.88 +	cam_clip(0.1, 200.0);
   11.89 +	cam_rotate(0, 0);
   11.90 +	cam_dolly(2);
   11.91 +
   11.92 +	msurf = msurf_create();
   11.93 +	msurf_eval_func(msurf, eval);
   11.94 +	msurf_vertex_func(msurf, vertex);
   11.95 +	msurf_threshold(msurf, threshold);
   11.96 +	msurf_resolution(msurf, RES, RES, RES);
   11.97 +	msurf_bounds(msurf, -1, -1, -1, 1, 1, 1);
   11.98 +
   11.99 +	glClearColor(0.8, 0.8, 0.8, 1.0);
  11.100 +
  11.101 +	if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) {
  11.102 +		return 1;
  11.103 +	}
  11.104 +
  11.105 +	glutMainLoop();
  11.106 +	return 0;
  11.107 +}
  11.108 +
  11.109 +float eval(float x, float y, float z)
  11.110 +{
  11.111 +	int i;
  11.112 +	float val = 0.0f;
  11.113 +
  11.114 +	for(i=0; i<num_mballs; i++) {
  11.115 +		float dx = mball[i].x - x;
  11.116 +		float dy = mball[i].y - y;
  11.117 +		float dz = mball[i].z - z;
  11.118 +		float dist_sq = dx * dx + dy * dy + dz * dz;
  11.119 +
  11.120 +		if(dist_sq < 1e-6) {
  11.121 +			val += 100.0;
  11.122 +		} else {
  11.123 +			val += mball[i].energy / dist_sq;
  11.124 +		}
  11.125 +	}
  11.126 +	return val;
  11.127 +}
  11.128 +
  11.129 +void vertex(float x, float y, float z)
  11.130 +{
  11.131 +	const float dt = 0.001;
  11.132 +	float dfdx = eval(x - dt, y, z) - eval(x + dt, y, z);
  11.133 +	float dfdy = eval(x, y - dt, z) - eval(x, y + dt, z);
  11.134 +	float dfdz = eval(x, y, z - dt) - eval(x, y, z + dt);
  11.135 +
  11.136 +	glNormal3f(dfdx, dfdy, dfdz);
  11.137 +	glVertex3f(x, y, z);
  11.138 +}
  11.139 +
  11.140 +void render(void)
  11.141 +{
  11.142 +	float kd[] = {0.7, 0.28, 0.2, 1.0};
  11.143 +	float ks[] = {0.9, 0.9, 0.9, 1.0};
  11.144 +
  11.145 +	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd);
  11.146 +	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks);
  11.147 +	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0);
  11.148 +
  11.149 +	bind_program(sdr);
  11.150 +
  11.151 +	glBegin(GL_TRIANGLES);
  11.152 +	msurf_polygonize(msurf);
  11.153 +	glEnd();
  11.154 +
  11.155 +	assert(glGetError() == GL_NO_ERROR);
  11.156 +}
  11.157 +
  11.158 +void disp(void)
  11.159 +{
  11.160 +	if(stereo) {
  11.161 +		glDrawBuffer(GL_BACK_LEFT);
  11.162 +	}
  11.163 +
  11.164 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  11.165 +
  11.166 +	glMatrixMode(GL_PROJECTION);
  11.167 +	glLoadIdentity();
  11.168 +	cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER);
  11.169 +
  11.170 +	glMatrixMode(GL_MODELVIEW);
  11.171 +	glLoadIdentity();
  11.172 +	cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER);
  11.173 +
  11.174 +	render();
  11.175 +
  11.176 +	if(stereo) {
  11.177 +		glDrawBuffer(GL_BACK_RIGHT);
  11.178 +		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  11.179 +
  11.180 +		glMatrixMode(GL_PROJECTION);
  11.181 +		glLoadIdentity();
  11.182 +		cam_stereo_proj_matrix(CAM_RIGHT);
  11.183 +
  11.184 +		glMatrixMode(GL_MODELVIEW);
  11.185 +		glLoadIdentity();
  11.186 +		cam_stereo_view_matrix(CAM_RIGHT);
  11.187 +
  11.188 +		render();
  11.189 +	}
  11.190 +	glutSwapBuffers();
  11.191 +}
  11.192 +
  11.193 +void reshape(int x, int y)
  11.194 +{
  11.195 +	glViewport(0, 0, x, y);
  11.196 +	cam_aspect((float)x / (float)y);
  11.197 +}
  11.198 +
  11.199 +void keyb(unsigned char key, int x, int y)
  11.200 +{
  11.201 +	static int wire;
  11.202 +
  11.203 +	switch(key) {
  11.204 +	case 27:
  11.205 +		exit(0);
  11.206 +
  11.207 +	case 's':
  11.208 +		stereo = !stereo;
  11.209 +		glutPostRedisplay();
  11.210 +		break;
  11.211 +
  11.212 +	case 'w':
  11.213 +		wire = !wire;
  11.214 +		glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL);
  11.215 +		glutPostRedisplay();
  11.216 +		break;
  11.217 +
  11.218 +	case '=':
  11.219 +		threshold += 0.05;
  11.220 +		msurf_threshold(msurf, threshold);
  11.221 +		printf("threshold: %f\n", threshold);
  11.222 +		glutPostRedisplay();
  11.223 +		break;
  11.224 +
  11.225 +	case '-':
  11.226 +		threshold -= 0.05;
  11.227 +		msurf_threshold(msurf, threshold);
  11.228 +		printf("threshold: %f\n", threshold);
  11.229 +		glutPostRedisplay();
  11.230 +		break;
  11.231 +
  11.232 +	case ' ':
  11.233 +		bidx = (bidx + 1) % num_mballs;
  11.234 +		break;
  11.235 +
  11.236 +	default:
  11.237 +		break;
  11.238 +	}
  11.239 +}
  11.240 +
  11.241 +int bnstate[32];
  11.242 +int prev_x, prev_y;
  11.243 +
  11.244 +void mouse(int bn, int state, int x, int y)
  11.245 +{
  11.246 +	bnstate[bn] = state == GLUT_DOWN;
  11.247 +	prev_x = x;
  11.248 +	prev_y = y;
  11.249 +}
  11.250 +
  11.251 +void motion(int x, int y)
  11.252 +{
  11.253 +	int dx, dy;
  11.254 +
  11.255 +	dx = x - prev_x;
  11.256 +	dy = y - prev_y;
  11.257 +	prev_x = x;
  11.258 +	prev_y = y;
  11.259 +
  11.260 +	if(bnstate[GLUT_LEFT_BUTTON]) {
  11.261 +		cam_inp_rotate(dx, dy);
  11.262 +		glutPostRedisplay();
  11.263 +	}
  11.264 +	if(bnstate[GLUT_RIGHT_BUTTON]) {
  11.265 +		cam_inp_zoom(dy);
  11.266 +		glutPostRedisplay();
  11.267 +	}
  11.268 +}
  11.269 +
  11.270 +void sball_button(int bn, int state)
  11.271 +{
  11.272 +	if(state) return;
  11.273 +
  11.274 +	if(bn < num_mballs) {
  11.275 +		bidx = bn;
  11.276 +	} else {
  11.277 +		bidx = (bidx + 1) % num_mballs;
  11.278 +	}
  11.279 +}
  11.280 +
  11.281 +void sball_motion(int x, int y, int z)
  11.282 +{
  11.283 +	mball[bidx].x += (float)x / 32768.0;
  11.284 +	mball[bidx].y += (float)y / 32768.0;
  11.285 +	mball[bidx].z -= (float)z / 32768.0;
  11.286 +	glutPostRedisplay();
  11.287 +}
  11.288 +
  11.289 +int parse_args(int argc, char **argv)
  11.290 +{
  11.291 +	int i;
  11.292 +
  11.293 +	for(i=1; i<argc; i++) {
  11.294 +		if(argv[i][0] == '-' && argv[i][2] == 0) {
  11.295 +			switch(argv[i][1]) {
  11.296 +			case 's':
  11.297 +				stereo = !stereo;
  11.298 +				break;
  11.299 +
  11.300 +			default:
  11.301 +				fprintf(stderr, "unrecognized option: %s\n", argv[i]);
  11.302 +				return -1;
  11.303 +			}
  11.304 +		} else {
  11.305 +			fprintf(stderr, "unexpected argument: %s\n", argv[i]);
  11.306 +			return -1;
  11.307 +		}
  11.308 +	}
  11.309 +	return 0;
  11.310 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/mcubes.h	Tue Oct 25 07:34:31 2011 +0300
    12.3 @@ -0,0 +1,294 @@
    12.4 +static int mc_edge_table[256] = {
    12.5 +	0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
    12.6 +	0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
    12.7 +	0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
    12.8 +	0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
    12.9 +	0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
   12.10 +	0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
   12.11 +	0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
   12.12 +	0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
   12.13 +	0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
   12.14 +	0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
   12.15 +	0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
   12.16 +	0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
   12.17 +	0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
   12.18 +	0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
   12.19 +	0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
   12.20 +	0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
   12.21 +	0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
   12.22 +	0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
   12.23 +	0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
   12.24 +	0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
   12.25 +	0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
   12.26 +	0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
   12.27 +	0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
   12.28 +	0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
   12.29 +	0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
   12.30 +	0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
   12.31 +	0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
   12.32 +	0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
   12.33 +	0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
   12.34 +	0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
   12.35 +	0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
   12.36 +	0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
   12.37 +};
   12.38 +
   12.39 +
   12.40 +static int mc_tri_table[256][16] = {
   12.41 +	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.42 +	{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.43 +	{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.44 +	{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.45 +	{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.46 +	{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.47 +	{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.48 +	{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
   12.49 +	{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.50 +	{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.51 +	{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.52 +	{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
   12.53 +	{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.54 +	{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
   12.55 +	{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
   12.56 +	{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.57 +	{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.58 +	{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.59 +	{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.60 +	{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
   12.61 +	{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.62 +	{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
   12.63 +	{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
   12.64 +	{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
   12.65 +	{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.66 +	{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
   12.67 +	{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
   12.68 +	{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
   12.69 +	{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
   12.70 +	{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
   12.71 +	{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
   12.72 +	{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
   12.73 +	{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.74 +	{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.75 +	{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.76 +	{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
   12.77 +	{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.78 +	{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
   12.79 +	{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
   12.80 +	{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
   12.81 +	{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.82 +	{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
   12.83 +	{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
   12.84 +	{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
   12.85 +	{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
   12.86 +	{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
   12.87 +	{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
   12.88 +	{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
   12.89 +	{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.90 +	{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
   12.91 +	{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
   12.92 +	{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
   12.93 +	{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
   12.94 +	{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
   12.95 +	{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
   12.96 +	{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
   12.97 +	{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
   12.98 +	{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
   12.99 +	{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
  12.100 +	{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  12.101 +	{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
  12.102 +	{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
  12.103 +	{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
  12.104 +	{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.105 +	{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.106 +	{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.107 +	{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.108 +	{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  12.109 +	{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.110 +	{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
  12.111 +	{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  12.112 +	{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
  12.113 +	{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.114 +	{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  12.115 +	{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  12.116 +	{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
  12.117 +	{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  12.118 +	{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  12.119 +	{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
  12.120 +	{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  12.121 +	{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.122 +	{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
  12.123 +	{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  12.124 +	{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  12.125 +	{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
  12.126 +	{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
  12.127 +	{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
  12.128 +	{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
  12.129 +	{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  12.130 +	{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  12.131 +	{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
  12.132 +	{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
  12.133 +	{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  12.134 +	{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
  12.135 +	{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
  12.136 +	{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
  12.137 +	{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.138 +	{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
  12.139 +	{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  12.140 +	{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  12.141 +	{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  12.142 +	{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
  12.143 +	{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.144 +	{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  12.145 +	{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
  12.146 +	{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
  12.147 +	{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  12.148 +	{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
  12.149 +	{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
  12.150 +	{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
  12.151 +	{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  12.152 +	{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.153 +	{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  12.154 +	{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
  12.155 +	{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
  12.156 +	{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  12.157 +	{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  12.158 +	{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
  12.159 +	{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  12.160 +	{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.161 +	{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  12.162 +	{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
  12.163 +	{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
  12.164 +	{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
  12.165 +	{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
  12.166 +	{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.167 +	{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
  12.168 +	{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.169 +	{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.170 +	{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.171 +	{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.172 +	{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  12.173 +	{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.174 +	{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  12.175 +	{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  12.176 +	{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
  12.177 +	{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.178 +	{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  12.179 +	{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
  12.180 +	{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
  12.181 +	{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  12.182 +	{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
  12.183 +	{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
  12.184 +	{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  12.185 +	{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.186 +	{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  12.187 +	{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
  12.188 +	{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
  12.189 +	{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
  12.190 +	{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
  12.191 +	{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
  12.192 +	{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
  12.193 +	{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  12.194 +	{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.195 +	{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
  12.196 +	{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  12.197 +	{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
  12.198 +	{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  12.199 +	{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
  12.200 +	{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.201 +	{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.202 +	{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  12.203 +	{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  12.204 +	{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
  12.205 +	{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  12.206 +	{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
  12.207 +	{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
  12.208 +	{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
  12.209 +	{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
  12.210 +	{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
  12.211 +	{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
  12.212 +	{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
  12.213 +	{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
  12.214 +	{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
  12.215 +	{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
  12.216 +	{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
  12.217 +	{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  12.218 +	{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
  12.219 +	{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
  12.220 +	{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  12.221 +	{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
  12.222 +	{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
  12.223 +	{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
  12.224 +	{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
  12.225 +	{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
  12.226 +	{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  12.227 +	{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
  12.228 +	{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.229 +	{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
  12.230 +	{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
  12.231 +	{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.232 +	{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.233 +	{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.234 +	{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
  12.235 +	{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
  12.236 +	{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
  12.237 +	{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  12.238 +	{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
  12.239 +	{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
  12.240 +	{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
  12.241 +	{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  12.242 +	{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
  12.243 +	{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
  12.244 +	{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
  12.245 +	{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.246 +	{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  12.247 +	{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  12.248 +	{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.249 +	{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  12.250 +	{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
  12.251 +	{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
  12.252 +	{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
  12.253 +	{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
  12.254 +	{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
  12.255 +	{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
  12.256 +	{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.257 +	{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
  12.258 +	{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  12.259 +	{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
  12.260 +	{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
  12.261 +	{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  12.262 +	{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.263 +	{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
  12.264 +	{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.265 +	{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  12.266 +	{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
  12.267 +	{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
  12.268 +	{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
  12.269 +	{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
  12.270 +	{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
  12.271 +	{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  12.272 +	{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
  12.273 +	{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
  12.274 +	{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
  12.275 +	{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
  12.276 +	{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.277 +	{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  12.278 +	{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
  12.279 +	{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.280 +	{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.281 +	{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.282 +	{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  12.283 +	{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  12.284 +	{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.285 +	{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  12.286 +	{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
  12.287 +	{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.288 +	{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.289 +	{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  12.290 +	{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.291 +	{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
  12.292 +	{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.293 +	{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.294 +	{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.295 +	{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  12.296 +	{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
  12.297 +};
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/metasurf.c	Tue Oct 25 07:34:31 2011 +0300
    13.3 @@ -0,0 +1,362 @@
    13.4 +#include <stdlib.h>
    13.5 +#include "metasurf.h"
    13.6 +#include "mcubes.h"
    13.7 +
    13.8 +#undef USE_MTETRA
    13.9 +#define USE_MCUBES
   13.10 +
   13.11 +#if (defined(USE_MTETRA) && defined(USE_MCUBES)) || (!defined(USE_MTETRA) && !defined(USE_MCUBES))
   13.12 +#error "pick either USE_MTETRA or USE_MCUBES, not both..."
   13.13 +#endif
   13.14 +
   13.15 +typedef float vec3[3];
   13.16 +
   13.17 +struct metasurface {
   13.18 +	vec3 min, max;
   13.19 +	int res[3];
   13.20 +	float thres;
   13.21 +
   13.22 +	msurf_eval_func_t eval;
   13.23 +	msurf_vertex_func_t vertex;
   13.24 +	msurf_normal_func_t normal;
   13.25 +
   13.26 +	vec3 vbuf[3];
   13.27 +	int nverts;
   13.28 +};
   13.29 +
   13.30 +static int msurf_init(struct metasurface *ms);
   13.31 +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz);
   13.32 +#ifdef USE_MTETRA
   13.33 +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val);
   13.34 +#endif
   13.35 +#ifdef USE_MCUBES
   13.36 +static void process_cube(struct metasurface *ms, vec3 *pos, float *val);
   13.37 +#endif
   13.38 +
   13.39 +
   13.40 +struct metasurface *msurf_create(void)
   13.41 +{
   13.42 +	struct metasurface *ms;
   13.43 +
   13.44 +	if(!(ms = malloc(sizeof *ms))) {
   13.45 +		return 0;
   13.46 +	}
   13.47 +	if(msurf_init(ms) == -1) {
   13.48 +		free(ms);
   13.49 +	}
   13.50 +	return ms;
   13.51 +}
   13.52 +
   13.53 +void msurf_free(struct metasurface *ms)
   13.54 +{
   13.55 +	free(ms);
   13.56 +}
   13.57 +
   13.58 +static int msurf_init(struct metasurface *ms)
   13.59 +{
   13.60 +	ms->thres = 0.0;
   13.61 +	ms->eval = 0;
   13.62 +	ms->vertex = 0;
   13.63 +	ms->normal = 0;
   13.64 +	ms->min[0] = ms->min[1] = ms->min[2] = -1.0;
   13.65 +	ms->max[0] = ms->max[1] = ms->max[2] = 1.0;
   13.66 +	ms->res[0] = ms->res[1] = ms->res[2] = 32;
   13.67 +	ms->nverts = 0;
   13.68 +
   13.69 +	return 0;
   13.70 +}
   13.71 +
   13.72 +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func)
   13.73 +{
   13.74 +	ms->eval = func;
   13.75 +}
   13.76 +
   13.77 +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func)
   13.78 +{
   13.79 +	ms->vertex = func;
   13.80 +}
   13.81 +
   13.82 +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func)
   13.83 +{
   13.84 +	ms->normal = func;
   13.85 +}
   13.86 +
   13.87 +void msurf_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax)
   13.88 +{
   13.89 +	ms->min[0] = xmin;
   13.90 +	ms->min[1] = ymin;
   13.91 +	ms->min[2] = zmin;
   13.92 +	ms->max[0] = xmax;
   13.93 +	ms->max[1] = ymax;
   13.94 +	ms->max[2] = zmax;
   13.95 +}
   13.96 +
   13.97 +void msurf_resolution(struct metasurface *ms, int xres, int yres, int zres)
   13.98 +{
   13.99 +	ms->res[0] = xres;
  13.100 +	ms->res[1] = yres;
  13.101 +	ms->res[2] = zres;
  13.102 +}
  13.103 +
  13.104 +void msurf_threshold(struct metasurface *ms, float thres)
  13.105 +{
  13.106 +	ms->thres = thres;
  13.107 +}
  13.108 +
  13.109 +
  13.110 +void msurf_polygonize(struct metasurface *ms)
  13.111 +{
  13.112 +	int i, j, k;
  13.113 +	vec3 pos, delta;
  13.114 +
  13.115 +	for(i=0; i<3; i++) {
  13.116 +		delta[i] = (ms->max[i] - ms->min[i]) / (float)ms->res[i];
  13.117 +	}
  13.118 +
  13.119 +	pos[0] = ms->min[0];
  13.120 +	for(i=0; i<ms->res[0] - 1; i++) {
  13.121 +
  13.122 +		pos[1] = ms->min[1];
  13.123 +		for(j=0; j<ms->res[1] - 1; j++) {
  13.124 +
  13.125 +			pos[2] = ms->min[2];
  13.126 +			for(k=0; k<ms->res[2] - 1; k++) {
  13.127 +
  13.128 +				process_cell(ms, pos, delta);
  13.129 +
  13.130 +				pos[2] += delta[2];
  13.131 +			}
  13.132 +			pos[1] += delta[1];
  13.133 +		}
  13.134 +		pos[0] += delta[0];
  13.135 +	}
  13.136 +}
  13.137 +
  13.138 +
  13.139 +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz)
  13.140 +{
  13.141 +	int i;
  13.142 +	vec3 p[8];
  13.143 +	float val[8];
  13.144 +
  13.145 +#ifdef USE_MTETRA
  13.146 +	static int tetra[][4] = {
  13.147 +		{0, 2, 3, 7},
  13.148 +		{0, 2, 6, 7},
  13.149 +		{0, 4, 6, 7},
  13.150 +		{0, 6, 1, 2},
  13.151 +		{0, 6, 1, 4},
  13.152 +		{5, 6, 1, 4}
  13.153 +	};
  13.154 +#endif
  13.155 +
  13.156 +	static const float offs[][3] = {
  13.157 +		{0.0f, 0.0f, 0.0f},
  13.158 +		{1.0f, 0.0f, 0.0f},
  13.159 +		{1.0f, 1.0f, 0.0f},
  13.160 +		{0.0f, 1.0f, 0.0f},
  13.161 +		{0.0f, 0.0f, 1.0f},
  13.162 +		{1.0f, 0.0f, 1.0f},
  13.163 +		{1.0f, 1.0f, 1.0f},
  13.164 +		{0.0f, 1.0f, 1.0f}
  13.165 +	};
  13.166 +
  13.167 +	for(i=0; i<8; i++) {
  13.168 +		p[i][0] = pos[0] + sz[0] * offs[i][2];
  13.169 +		p[i][1] = pos[1] + sz[1] * offs[i][1];
  13.170 +		p[i][2] = pos[2] + sz[2] * offs[i][0];
  13.171 +
  13.172 +		val[i] = ms->eval(p[i][0], p[i][1], p[i][2]);
  13.173 +	}
  13.174 +
  13.175 +#ifdef USE_MTETRA
  13.176 +	for(i=0; i<6; i++) {
  13.177 +		process_tetra(ms, tetra[i], p, val);
  13.178 +	}
  13.179 +#endif
  13.180 +#ifdef USE_MCUBES
  13.181 +	process_cube(ms, p, val);
  13.182 +#endif
  13.183 +}
  13.184 +
  13.185 +
  13.186 +/* ---- marching cubes implementation ---- */
  13.187 +#ifdef USE_MCUBES
  13.188 +
  13.189 +static unsigned int mc_bitcode(float *val, float thres);
  13.190 +
  13.191 +static void process_cube(struct metasurface *ms, vec3 *pos, float *val)
  13.192 +{
  13.193 +	static const int pidx[12][2] = {
  13.194 +		{0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6},
  13.195 +		{6, 7},	{7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
  13.196 +	};
  13.197 +	int i, j;
  13.198 +	vec3 vert[12];
  13.199 +	unsigned int code = mc_bitcode(val, ms->thres);
  13.200 +
  13.201 +	if(mc_edge_table[code] == 0) {
  13.202 +		return;
  13.203 +	}
  13.204 +
  13.205 +	for(i=0; i<12; i++) {
  13.206 +		if(mc_edge_table[code] & (1 << i)) {
  13.207 +			int p0 = pidx[i][0];
  13.208 +			int p1 = pidx[i][1];
  13.209 +
  13.210 +			float t = (ms->thres - val[p0]) / (val[p1] - val[p0]);
  13.211 +			vert[i][0] = pos[p0][0] + (pos[p1][0] - pos[p0][0]) * t;
  13.212 +			vert[i][1] = pos[p0][1] + (pos[p1][1] - pos[p0][1]) * t;
  13.213 +			vert[i][2] = pos[p0][2] + (pos[p1][2] - pos[p0][2]) * t;
  13.214 +		}
  13.215 +	}
  13.216 +
  13.217 +	for(i=0; mc_tri_table[code][i] != -1; i+=3) {
  13.218 +		for(j=0; j<3; j++) {
  13.219 +			float *v = vert[mc_tri_table[code][i + j]];
  13.220 +			ms->vertex(v[0], v[1], v[2]);
  13.221 +		}
  13.222 +	}
  13.223 +}
  13.224 +
  13.225 +static unsigned int mc_bitcode(float *val, float thres)
  13.226 +{
  13.227 +	unsigned int i, res = 0;
  13.228 +
  13.229 +	for(i=0; i<8; i++) {
  13.230 +		if(val[i] > thres) {
  13.231 +			res |= 1 << i;
  13.232 +		}
  13.233 +	}
  13.234 +	return res;
  13.235 +}
  13.236 +#endif	/* USE_MCUBES */
  13.237 +
  13.238 +
  13.239 +/* ---- marching tetrahedra implementation (incomplete) ---- */
  13.240 +#ifdef USE_MTETRA
  13.241 +
  13.242 +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres);
  13.243 +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev)
  13.244 +
  13.245 +
  13.246 +#define REVBIT(x)	((x) & 8)
  13.247 +#define INV(x)		(~(x) & 0xf)
  13.248 +#define EDGE(a, b)	emmit(ms, val[idx[a]], val[idx[b]], pos[idx[a]], pos[idx[b]], REVBIT(code))
  13.249 +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val)
  13.250 +{
  13.251 +	unsigned int code = mt_bitcode(val[idx[0]], val[idx[1]], val[idx[2]], val[idx[3]], ms->thres);
  13.252 +
  13.253 +	switch(code) {
  13.254 +	/*case 1:
  13.255 +	case INV(1):*/
  13.256 +	case 0x0e:
  13.257 +	case 0x01:
  13.258 +		EDGE(0, 1);
  13.259 +		EDGE(0, 2);
  13.260 +		EDGE(0, 3);
  13.261 +		break;
  13.262 +
  13.263 +	/*case 2:
  13.264 +	case INV(2):*/
  13.265 +	case 0x0d:
  13.266 +	case 0x02:
  13.267 +		EDGE(1, 0);
  13.268 +		EDGE(1, 3);
  13.269 +		EDGE(1, 2);
  13.270 +		break;
  13.271 +
  13.272 +	/*case 3:
  13.273 +	case INV(3):*/
  13.274 +	case 0x0c:
  13.275 +	case 0x03:
  13.276 +		EDGE(0, 3);
  13.277 +		EDGE(0, 2);
  13.278 +		EDGE(1, 3);
  13.279 +
  13.280 +		EDGE(1, 3);
  13.281 +		EDGE(1, 2);
  13.282 +		EDGE(0, 2);
  13.283 +		break;
  13.284 +
  13.285 +	/*case 4:
  13.286 +	case INV(4):*/
  13.287 +	case 0x0b:
  13.288 +	case 0x04:
  13.289 +		EDGE(2, 0);
  13.290 +		EDGE(2, 1);
  13.291 +		EDGE(2, 3);
  13.292 +		break;
  13.293 +
  13.294 +	/*case 5:
  13.295 +	case INV(5):*/
  13.296 +	case 0x0a:
  13.297 +	case 0x05:
  13.298 +		EDGE(0, 1);
  13.299 +		EDGE(2, 3);
  13.300 +		EDGE(0, 3);
  13.301 +
  13.302 +		EDGE(0, 1);
  13.303 +		EDGE(1, 2);
  13.304 +		EDGE(2, 3);
  13.305 +		break;
  13.306 +
  13.307 +	/*case 6:
  13.308 +	case INV(6):*/
  13.309 +	case 0x09:
  13.310 +	case 0x06:
  13.311 +		EDGE(0, 1);
  13.312 +		EDGE(1, 3);
  13.313 +		EDGE(2, 3);
  13.314 +
  13.315 +		EDGE(0, 1);
  13.316 +		EDGE(0, 2);
  13.317 +		EDGE(2, 3);
  13.318 +		break;
  13.319 +
  13.320 +	/*case 7:
  13.321 +	case INV(7):*/
  13.322 +	case 0x07:
  13.323 +	case 0x08:
  13.324 +		EDGE(3, 0);
  13.325 +		EDGE(3, 2);
  13.326 +		EDGE(3, 1);
  13.327 +		break;
  13.328 +
  13.329 +	default:
  13.330 +		break;	/* cases 0 and 15 */
  13.331 +	}
  13.332 +}
  13.333 +
  13.334 +#define BIT(i)	((v##i > thres) ? (1 << i) : 0)
  13.335 +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres)
  13.336 +{
  13.337 +	return BIT(0) | BIT(1) | BIT(2) | BIT(3);
  13.338 +}
  13.339 +
  13.340 +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev)
  13.341 +{
  13.342 +	int i;
  13.343 +	float t = (ms->thres - v0) / (v1 - v0);
  13.344 +
  13.345 +	vec3 p;
  13.346 +	for(i=0; i<3; i++) {
  13.347 +		p[i] = p0[i] + (p1[i] - p0[i]) * t;
  13.348 +	}
  13.349 +	ms->vertex(p[0], p[1], p[2]);
  13.350 +
  13.351 +	/*for(i=0; i<3; i++) {
  13.352 +		ms->vbuf[ms->nverts][i] = p0[i] + (p1[i] - p0[i]) * t;
  13.353 +	}
  13.354 +
  13.355 +	if(++ms->nverts >= 3) {
  13.356 +		ms->nverts = 0;
  13.357 +
  13.358 +		for(i=0; i<3; i++) {
  13.359 +			int idx = rev ? (2 - i) : i;
  13.360 +			ms->vertex(ms->vbuf[idx][0], ms->vbuf[idx][1], ms->vbuf[idx][2]);
  13.361 +		}
  13.362 +	}*/
  13.363 +}
  13.364 +
  13.365 +#endif	/* USE_MTETRA */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/metasurf.h	Tue Oct 25 07:34:31 2011 +0300
    14.3 @@ -0,0 +1,31 @@
    14.4 +#ifndef METASURF_H_
    14.5 +#define METASURF_H_
    14.6 +
    14.7 +struct metasurface;
    14.8 +
    14.9 +typedef float (*msurf_eval_func_t)(float, float, float);
   14.10 +typedef void (*msurf_vertex_func_t)(float, float, float);
   14.11 +typedef void (*msurf_normal_func_t)(float, float, float);
   14.12 +
   14.13 +#ifdef __cplusplus
   14.14 +extern "C" {
   14.15 +#endif
   14.16 +
   14.17 +struct metasurface *msurf_create(void);
   14.18 +void msurf_free(struct metasurface *ms);
   14.19 +
   14.20 +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func);
   14.21 +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func);
   14.22 +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func);
   14.23 +
   14.24 +void msurf_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax);
   14.25 +void msurf_resolution(struct metasurface *ms, int xres, int yres, int zres);
   14.26 +void msurf_threshold(struct metasurface *ms, float thres);
   14.27 +
   14.28 +void msurf_polygonize(struct metasurface *ms);
   14.29 +
   14.30 +#ifdef __cplusplus
   14.31 +}
   14.32 +#endif
   14.33 +
   14.34 +#endif	/* METASURF_H_ */