summaryrefslogtreecommitdiffstats
path: root/src/render/Antennas.cpp
blob: 5e30aca2acba0c6208bc39562765b6b20c8a9732 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "common.h"

#include "main.h"
#include "Antennas.h"

CAntenna CAntennas::aAntennas[NUMANTENNAS];

void
CAntennas::Init(void)
{
	int i;
	for(i = 0; i < NUMANTENNAS; i++){
		aAntennas[i].active = false;
		aAntennas[i].updatedLastFrame = false;
	}
}

// Free antennas that aren't used anymore
void
CAntennas::Update(void)
{
	int i;

	for(i = 0; i < NUMANTENNAS; i++){
		if(aAntennas[i].active && !aAntennas[i].updatedLastFrame)
			aAntennas[i].active = false;
		aAntennas[i].updatedLastFrame = false;
	}
}

// Add a new one or update an old one
void
CAntennas::RegisterOne(uint32 id, CVector dir, CVector position, float length)
{
	int i, j;

	for(i = 0; i < NUMANTENNAS; i++)
		if(aAntennas[i].active && aAntennas[i].id == id)
			break;

	if(i >= NUMANTENNAS){
		// not found, register new one

		// find empty slot
		for(i = 0; i < NUMANTENNAS; i++)
			if(!aAntennas[i].active)
				break;

		// there is space
		if(i < NUMANTENNAS){
			aAntennas[i].active = true;
			aAntennas[i].updatedLastFrame = true;
			aAntennas[i].id = id;
			aAntennas[i].segmentLength = length/6.0f;
			for(j = 0; j < 6; j++){
				aAntennas[i].pos[j] = position + dir*j*aAntennas[i].segmentLength;
				aAntennas[i].speed[j] = CVector(0.0f, 0.0f, 0.0f);
			}
		}
	}else{
		// found, update
		aAntennas[i].Update(dir, position);
		aAntennas[i].updatedLastFrame = true;
	}
}

static RwIm3DVertex vertexbufferA[2];

void
CAntennas::Render(void)
{
	int i, j;

	PUSH_RENDERGROUP("CAntennas::Render");
	for(i = 0; i < NUMANTENNAS; i++){
		if(!aAntennas[i].active)
			continue;

		RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
		RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
		RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
		RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
		RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);

		for(j = 0; j < 5; j++){
			RwIm3DVertexSetRGBA(&vertexbufferA[0], 200, 200, 200, 100);
			RwIm3DVertexSetPos(&vertexbufferA[0],
				aAntennas[i].pos[j].x,
				aAntennas[i].pos[j].y,
				aAntennas[i].pos[j].z);
			RwIm3DVertexSetRGBA(&vertexbufferA[1], 200, 200, 200, 100);
			RwIm3DVertexSetPos(&vertexbufferA[1],
				aAntennas[i].pos[j+1].x,
				aAntennas[i].pos[j+1].y,
				aAntennas[i].pos[j+1].z);

			// LittleTest();
			if(RwIm3DTransform(vertexbufferA, 2, nil, 0)){
				RwIm3DRenderLine(0, 1);
				RwIm3DEnd();
			}
		}
	}

	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);

	POP_RENDERGROUP();
}

void
CAntenna::Update(CVector dir, CVector basepos)
{
	int i;

	pos[0] = basepos;
	pos[1] = basepos + dir*segmentLength;

	for(i = 2; i < 6; i++){
		CVector basedir = pos[i-1] - pos[i-2];
		CVector newdir = pos[i] - pos[i-1] +	// drag along
			dir*0.1f +	// also drag up a bit for stiffness
			speed[i];	// and keep moving
		newdir.Normalise();
		newdir *= segmentLength;
		CVector newpos = pos[i-1] + (basedir + newdir)/2.0f;
		speed[i] = (newpos - pos[i])*0.9f;
		pos[i] = newpos;
	}
}