summaryrefslogtreecommitdiff
path: root/src/engine/model.h
blob: 16f16299461e10b03d596ffe4da63fe8956de415 (plain) (blame)
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
66
67
68
69
enum { MDL_MD5, MDL_IQM, NUMMODELTYPES };

struct model {
	char *name;
	float spinyaw, spinpitch, offsetyaw, offsetpitch;
	bool collide, ellipsecollide, shadow, alphadepth, depthoffset;
	float scale;
	vec translate;
	BIH *bih;
	vec bbcenter, bbradius, bbextend, collidecenter, collideradius;
	float rejectradius, eyeheight, collidexyradius, collideheight;
	int batch;
	model(const char *name) : name(name ? newstring(name) : NULL), spinyaw(0), spinpitch(0), offsetyaw(0), offsetpitch(0), collide(true), ellipsecollide(false), shadow(true), alphadepth(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bih(0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), collidecenter(0, 0, 0), collideradius(-1, -1, -1), rejectradius(-1), eyeheight(0.9f), collidexyradius(0), collideheight(0), batch(-1) {}
	virtual ~model() { DELETEA(name); DELETEP(bih); }
	virtual void calcbb(vec &center, vec &radius) = 0;
	virtual void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a = NULL, const vec &color = vec(0, 0, 0), const vec &dir = vec(0, 0, 0), float transparent = 1) = 0;
	virtual bool load() = 0;
	virtual int type() const = 0;
	virtual BIH *setBIH() { return 0; }
	virtual bool skeletal() const { return false; }
	virtual void setshader(Shader *) {}
	virtual void setspec(float) {}
	virtual void setambient(float) {}
	virtual void setalphatest(float) {}
	virtual void setalphablend(bool) {}
	virtual void setfullbright(float) {}
	virtual void setcullface(bool) {}
	virtual void preloadBIH() { if(!bih) setBIH(); }
	virtual void preloadshaders() {}
	virtual void preloadmeshes() {}
	virtual void cleanup() {}
	virtual void startrender() {}
	virtual void endrender() {}
	void boundbox(vec &center, vec &radius) {
		if(bbradius.x < 0) {
			calcbb(bbcenter, bbradius);
			bbradius.add(bbextend);
		}
		center = bbcenter;
		radius = bbradius;
	}
	float collisionbox(vec &center, vec &radius) {
		if(collideradius.x < 0) {
			boundbox(collidecenter, collideradius);
			if(collidexyradius) {
				collidecenter.x = collidecenter.y = 0;
				collideradius.x = collideradius.y = collidexyradius;
			}
			if(collideheight) {
				collidecenter.z = collideradius.z = collideheight/2;
			}
			rejectradius = vec(collidecenter).abs().add(collideradius).magnitude();
		}
		center = collidecenter;
		radius = collideradius;
		return rejectradius;
	}
	float boundsphere(vec &center) {
		vec radius;
		boundbox(center, radius);
		return radius.magnitude();
	}
	float above() {
		vec center, radius;
		boundbox(center, radius);
		return center.z+radius.z;
	}
};