Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / universesim / src / visualise.c
1 /*
2  * Tiny Universe Simulator
3  * By John Hodge (thePowersGang)
4  *
5  * visualise.c - Displays a visual representation of the universe
6  */
7 #include <common.h>
8 #include <tParticle.h>
9 #include <video.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
13
14 //#define VIEW_ALGO     all
15 #define VIEW_ALGO       avg
16
17 #define VIEW_AVG_SCALE  3
18
19 typedef struct sPixel
20 {
21         size_t  Mass;   // R
22         size_t  Charge; // G
23         size_t  Num;    // B
24 }       tPixel;
25
26 // === PROTOTYPES ===
27 void    Visualiser_GetBounds(void);
28 void    Visualiser_FillBuffers(void);
29 void    Visualiser_Render(void);
30
31 // === GLOBALS ===
32  int    giVisualiserPxWidth = 800;
33  int    giVisualiserPxHeight = 600;
34 tPixel  gVisualiser_MaxPixelVals;
35  int    giVisualiser_MinCharge = 0;
36 tPixel  *gVisualiserBuffer;
37 tVector gVisualiserBase;
38 tVector gVisualiserSize;
39 tMatrix gVisualiserView;
40 tLargeInt       gVisualiserMaxMass;
41 tLargeInt       gVisualiserMaxCharge;
42
43 // === CODE ===
44 void Visualiser_Initialise(void)
45 {
46         Matrix_SetIdentity(&gVisualiserView);
47         gVisualiserBuffer = malloc( giVisualiserPxWidth*giVisualiserPxHeight*sizeof(tPixel) );
48         Video_SetResolution( giVisualiserPxWidth, giVisualiserPxHeight );
49 }
50
51 void Visualiser_Update(void)
52 {
53         Visualiser_GetBounds();
54         Visualiser_FillBuffers();
55         Visualiser_Render();
56 }
57
58 /**
59  * \brief Scan all particles and get the populated volume
60  */
61 void Visualiser_GetBounds(void)
62 {
63          int    i;
64         tVector max, min;
65         
66         #if VIEW_ALGO == avg
67         // Average Distance around Average Position
68         // - Far less volatile than ViewAll
69         tVector avg, tmp, distV;
70         tLargeInt       numPart;
71         
72         Vector_Zero(&avg);
73         Vector_Zero(&distV);
74         LargeInt_SetNative(&numPart, giNumParticles, 0);
75         
76         // Get the average position
77         for( i = 0; i < giNumParticles; i++ )
78         {
79                 Vector_Add(&avg, &gpParticles[i].Location);
80                 
81                 if( LargeInt_Compare(&gVisualiserMaxMass, &gpParticles[i].Mass) < 0 )
82                         LargeInt_Set(&gVisualiserMaxMass, &gpParticles[i].Mass);
83                         
84                 if( LargeInt_Compare(&gVisualiserMaxCharge, &gpParticles[i].Charge) < 0 )
85                         LargeInt_Set(&gVisualiserMaxCharge, &gpParticles[i].Charge);
86         }
87         Vector_DivScalar(&avg, &numPart);
88         // Get the average distance from that position
89         for( i = 0; i < giNumParticles; i++ )
90         {
91                 Vector_Set(&tmp, &gpParticles[i].Location);
92                 Vector_Sub(&tmp, &avg);
93                 Vector_Abs(&tmp);
94                 Vector_Add(&distV, &tmp);
95         }
96         //LargeInt_Div(&dist, NULL, &dist, &numPart);
97         LargeInt_DivNative(&numPart, NULL, &numPart, VIEW_AVG_SCALE);
98         Vector_DivScalar(&distV, &numPart);
99         
100         //for( i = 0; i < VECTOR_COMPONENTS; i ++ )
101         //      LargeInt_Set(&distV.C[0], &dist);
102         
103         Vector_Set(&min, &avg);
104         Vector_Sub(&min, &distV);
105         Vector_Set(&max, &avg);
106         Vector_Add(&max, &distV);
107         
108         #else
109         // View All
110         // - Ensures that all particles are on screen at the same time
111                 
112         Vector_Set(&max, &gpParticles[0].Location);
113         Vector_Set(&min, &gpParticles[0].Location);
114         //Vector_Zero(&min);    Vector_Zero(&max);
115         LargeInt_Zero(&gVisualiserMaxMass);
116         LargeInt_Zero(&gVisualiserMaxCharge);
117         
118         for( i = 1; i < giNumParticles; i++ )
119         {
120                 Vector_GetMax(&max, &max, &gpParticles[i].Location);
121                 Vector_GetMin(&min, &min, &gpParticles[i].Location);
122                 
123                 
124                 //printf( "gpParticles[%i].Location = %s\n", i, Vector_DumpEx(&gpParticles[i].Location, 0) );
125                 
126                 if( LargeInt_Compare(&gVisualiserMaxMass, &gpParticles[i].Mass) < 0 )
127                         LargeInt_Set(&gVisualiserMaxMass, &gpParticles[i].Mass);
128                         
129                 if( LargeInt_Compare(&gVisualiserMaxCharge, &gpParticles[i].Charge) < 0 )
130                         LargeInt_Set(&gVisualiserMaxCharge, &gpParticles[i].Charge);
131         }
132         
133         //printf("max = %s, min = %s\n", Vector_DumpEx(&max, 0), Vector_DumpEx(&min, 1));
134         
135         //printf("gVisualiserMaxMass = %s, gVisualiserMaxCharge = %s\n",
136         //      LargeInt_DumpEx(&gVisualiserMaxMass, 0),
137         //      LargeInt_DumpEx(&gVisualiserMaxCharge, 1)
138         //      );
139         #endif
140         
141         Vector_Set( &gVisualiserBase, &min );
142         Vector_Set( &gVisualiserSize, &max );
143         Vector_Sub( &gVisualiserSize, &min );
144         
145         //printf("gVisualiserBase = %s\n", Vector_DumpEx(&gVisualiserBase, 0) );
146         //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 2) );
147         
148         Vector_MulMatrix(&gVisualiserBase, &gVisualiserView, &gVisualiserBase);
149         Vector_MulMatrix(&gVisualiserSize, &gVisualiserView, &gVisualiserSize);
150         
151         //printf("gVisualiserBase = %s\n", Vector_DumpEx(&gVisualiserBase, 0) );
152         //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 2) );
153 }
154
155 /**
156  * \brief Fill the buffer from the particles
157  */
158 void Visualiser_FillBuffers(void)
159 {
160         tVector tmp;
161         tLargeInt       tmpLI;
162          int    i, x, y;
163         tPixel  *px;
164         
165         memset( gVisualiserBuffer, 0, sizeof(tPixel)*giVisualiserPxHeight*giVisualiserPxWidth );
166         
167         for( i = 0; i < giNumParticles; i++ )
168         {
169                 Vector_Set(&tmp, &gpParticles[i].Location);
170                 Vector_MulMatrix(&tmp, &gVisualiserView, &tmp);
171                 Vector_Sub(&tmp, &gVisualiserBase);
172                 
173                 LargeInt_MulNative(&tmp.C[0], NULL, &tmp.C[0], giVisualiserPxWidth-1);
174                 LargeInt_MulNative(&tmp.C[1], NULL, &tmp.C[1], giVisualiserPxHeight-1);
175                 
176                 //printf("tmp             = %s\n", Vector_DumpEx(&tmp, 0));
177                 //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 0));
178                 Vector_DivComp(&tmp, &gVisualiserSize);
179                 //printf("tmp = %s\n", Vector_DumpEx(&tmp, 0));
180                 
181                 //exit(-1);
182                 
183                 // Both components are now known to be machine integers, as
184                 // giVisualiserPxWidth and giVisualiserPxHeight are native integers
185                 x = tmp.C[0].W[0];      y = tmp.C[1].W[0];
186                 if( x < 0 || x >= giVisualiserPxWidth ) continue;
187                 if( y < 0 || y >= giVisualiserPxHeight )        continue;
188                 //printf("Particle #%i (%i,%i)\n", i, x, y);
189                 
190                 // Set Pixel information
191                 px = &gVisualiserBuffer[y*giVisualiserPxWidth+x];
192                 
193                 LargeInt_MulNative( &tmpLI, NULL, &gpParticles[i].Mass, 100);
194                 LargeInt_Div( &tmpLI, NULL, &tmpLI, &gVisualiserMaxMass);
195                 px->Mass += tmpLI.W[0];
196                 
197                 LargeInt_MulNative( &tmpLI, NULL, &gpParticles[i].Charge, 100);
198                 LargeInt_Div( &tmpLI, NULL, &tmpLI, &gVisualiserMaxCharge);
199                 px->Charge += tmpLI.W[0];
200                 
201                 px->Num ++;
202                 
203                 //printf("(%i,%i) = (%i,%i,%i)\n", x, y, px->Mass, px->Charge, px->Num);
204                 
205                 if( i == 0 )
206                 {
207                         giVisualiser_MinCharge = px->Charge;
208                         gVisualiser_MaxPixelVals.Mass = px->Mass;
209                         gVisualiser_MaxPixelVals.Charge = px->Charge;
210                         gVisualiser_MaxPixelVals.Num = px->Num;
211                 }
212                 else
213                 {
214                         if(gVisualiser_MaxPixelVals.Mass < px->Mass)
215                                 gVisualiser_MaxPixelVals.Mass = px->Mass;
216                         if((int)gVisualiser_MaxPixelVals.Charge < (int)px->Charge)
217                                 gVisualiser_MaxPixelVals.Charge = px->Charge;
218                         if(giVisualiser_MinCharge > (int)px->Charge)
219                                 giVisualiser_MinCharge = (int)px->Charge;
220                         if(gVisualiser_MaxPixelVals.Num < px->Num)
221                                 gVisualiser_MaxPixelVals.Num = px->Num;
222                 }
223         }
224 }
225
226 #if 0
227 void Video_PSet(int x, int y, uint8_t r, uint8_t g, uint8_t b)
228 {
229         printf(" (%i,%i) %02x %02x %02x\n", x, y, r, g, b);
230 }
231 #endif
232
233 /**
234  * \brief Renders the buffer to the screen
235  */
236 void Visualiser_Render(void)
237 {
238          int    x, y;
239         tPixel  *px;
240         uint8_t r, g, b;
241         
242         //printf("gVisualiser_MaxPixelVals = {\n");
243         //printf(" Mass: %u\n", gVisualiser_MaxPixelVals.Mass);
244         //printf(" Charge: %i\n", gVisualiser_MaxPixelVals.Charge);
245         //printf(" Num: %u\n", gVisualiser_MaxPixelVals.Num);
246         //printf("}\n");
247         
248         //if(gVisualiser_MaxPixelVals.Mass ==0) gVisualiser_MaxPixelVals.Mass = 1;
249         //if(gVisualiser_MaxPixelVals.Charge ==0)       gVisualiser_MaxPixelVals.Charge = 1;
250         //if(gVisualiser_MaxPixelVals.Num ==0)  gVisualiser_MaxPixelVals.Num = 1;
251         
252         gVisualiser_MaxPixelVals.Charge -= giVisualiser_MinCharge;
253         
254         px = &gVisualiserBuffer[0];
255         for( y = 0; y < giVisualiserPxHeight; y ++ )
256         {
257                 for( x = 0; x < giVisualiserPxWidth; x ++ )
258                 {
259                         if( px->Num != 0 ) {
260                                 r = 255 * px->Mass / gVisualiser_MaxPixelVals.Mass;
261                                 g = 255 * (px->Charge - giVisualiser_MinCharge) / gVisualiser_MaxPixelVals.Charge;
262                                 b = 255 * px->Num / gVisualiser_MaxPixelVals.Num;
263                                 //if(g != 0x7f)
264                                 //      printf(" (%i,%i) %02x %02x %02x\n", x, y, r, g, b);
265                         }
266                         else {
267                                 r = g = b = 0;
268                         }
269                         Video_PSet(x, y, r, g, b);
270                         px ++;
271                 }
272         }
273         
274         Video_Flip();
275 }

UCC git Repository :: git.ucc.asn.au