aboutsummaryrefslogtreecommitdiff
path: root/obj.c
blob: 9f2a9d9d2a366c0b20931e4bdd0c58caf70f782a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <bio.h>
#include <draw.h>
#include "dat.h"
#include "fns.h"

Vector3 *verts;
Triangle3 *tris;
int nvert, ntri;
int lineno;

int
objread(char *f, Triangle3 **mesh)
{
	Biobuf *bin;
	char *s;
	int idx;
	double *coord;
	Vector3 *vert;

	bin = Bopen(f, OREAD);
	if(bin == nil)
		sysfatal("Bopen: %r");
	while((s = Brdline(bin, '\n')) != nil){
		lineno++;
		if(*s == 'v'){
			verts = erealloc(verts, ++nvert*sizeof(Vector3));
			coord = (double *)(verts+nvert-1);
			while(*s != '\n' && (Vector3 *)coord-verts < nvert){
				while(isspace(*++s))
					;
				*coord++ = strtod(s, &s);
			}
			if(coord-(double *)(verts+nvert-1) < 3){
				werrstr("%s:%d insufficient coordinates", f, lineno);
				goto error;
			}
		}
		if(*s == 'f'){
			tris = erealloc(tris, ++ntri*sizeof(Triangle3));
			vert = (Vector3 *)(tris+ntri-1);
			while(*s != '\n' && (Triangle3 *)vert-tris < ntri){
				while(isspace(*++s))
					;
				idx = strtol(s, &s, 0);
				if(idx > nvert){
					werrstr("%s:%d insufficient vertices", f, lineno);
					goto error;
				}
				*vert++ = verts[idx-1];
			}
		}
	}
	*mesh = tris;
	free(verts);
	Bterm(bin);
	return ntri;
error:
	free(verts);
	free(tris);
	Bterm(bin);
	return -1;
}