@@ -69,6 +69,87 @@ int g_drawnCells;
6969int g_drawnModels;
7070int g_drawnPolygons;
7171
72+ void DrawCellObject (const CELL_OBJECT& co, const Vector3D& cameraPos, float cameraAngleY, const Volume& frustrumVolume, bool buildingLighting)
73+ {
74+ if (co.type >= MAX_MODELS)
75+ {
76+ // WHAT THE FUCK?
77+ return ;
78+ }
79+
80+ Vector3D absCellPosition = FromFixedVector (co.pos );
81+ absCellPosition.y *= -1 .0f ;
82+
83+ const float distanceFromCamera = lengthSqr (absCellPosition - cameraPos);
84+
85+ ModelRef_t* ref = GetModelCheckLods (co.type , distanceFromCamera);
86+
87+ if (!ref->model )
88+ return ;
89+
90+ MODEL* model = ref->model ;
91+
92+ CRenderModel* renderModel = (CRenderModel*)ref->userData ;
93+
94+ if (!renderModel)
95+ return ;
96+
97+ // check if it is in view
98+ const float boundSphere = model->bounding_sphere * RENDER_SCALING * 2 .0f ;
99+
100+ if (!frustrumVolume.IsSphereInside (absCellPosition, boundSphere))
101+ return ;
102+
103+ bool isGround = false ;
104+
105+ if ((model->shape_flags & (SHAPE_FLAG_WATER | SHAPE_FLAG_TILE)) ||
106+ (model->flags2 & (MODEL_FLAG_PATH | MODEL_FLAG_GRASS)))
107+ {
108+ isGround = true ;
109+ }
110+
111+ // compute world matrix
112+ {
113+ Matrix4x4 objectMatrix;
114+
115+ if (model->shape_flags & SHAPE_FLAG_SPRITE)
116+ {
117+ objectMatrix = rotateY4 (DEG2RAD (cameraAngleY));
118+ }
119+ else
120+ {
121+ const float cellRotationRad = -co.yang / 64 .0f * PI_F * 2 .0f ;
122+ objectMatrix = rotateY4 (cellRotationRad);
123+ }
124+
125+ objectMatrix.setTranslationTransposed (absCellPosition);
126+
127+ GR_SetMatrix (MATRIX_WORLD, objectMatrix);
128+ GR_UpdateMatrixUniforms ();
129+ }
130+
131+ const float nightAmbientScale = 0 .35f ;
132+ const float nightLightScale = 0 .0f ;
133+
134+ const float ambientScale = 1 .0f ;
135+ const float lightScale = 1.0 ;
136+
137+ // apply lighting
138+ if ((isGround || !buildingLighting) && g_nightMode)
139+ CRenderModel::SetupLightingProperties (nightAmbientScale, nightLightScale);
140+ else
141+ CRenderModel::SetupLightingProperties (ambientScale, lightScale);
142+
143+ renderModel->Draw ();
144+
145+ g_drawnModels++;
146+ g_drawnPolygons += ref->model ->num_polys ;
147+
148+ // debug
149+ if (g_displayCollisionBoxes)
150+ CRenderModel::DrawModelCollisionBox (ref, co.pos , co.yang );
151+ }
152+
72153struct PCO_PAIR_D2
73154{
74155 PACKED_CELL_OBJECT* pco;
@@ -103,30 +184,6 @@ void DrawLevelDriver2(const Vector3D& cameraPos, float cameraAngleY, const Volum
103184
104185 levMapDriver2->WorldPositionToCellXZ (cell, cameraPosition);
105186
106- /*
107- int cameraAngleY = g_cameraAngles.y * (4096.0f / 360.0f);
108- int FrAng = 512;
109-
110- // setup planes
111- int backPlane = 6144;
112- int rightPlane = -6144;
113- int leftPlane = 6144;
114-
115- int farClipLimit = 280000;
116-
117- int rightAng = cameraAngleY - FrAng & 0xfff;
118- int leftAng = cameraAngleY + FrAng & 0xfff;
119- int backAng = cameraAngleY + 1024 & 0xfff;
120-
121- int rightcos = icos(rightAng);
122- int rightsin = isin(rightAng);
123-
124- int leftcos = icos(leftAng);
125- int leftsin = isin(leftAng);
126- int backcos = icos(backAng);
127- int backsin = isin(backAng);
128- */
129-
130187 static Array<PCO_PAIR_D2> drawObjects;
131188 drawObjects.reserve (g_cellsDrawDistance * 2 );
132189 drawObjects.clear ();
@@ -162,7 +219,7 @@ void DrawLevelDriver2(const Vector3D& cameraPos, float cameraAngleY, const Volum
162219 // walk each cell object in cell
163220 while (ppco)
164221 {
165- if (ci.listType != 0 && !g_displayAllCellLevels)
222+ if (ci.listType != - 1 && !g_displayAllCellLevels)
166223 break ;
167224
168225 PCO_PAIR_D2 pair;
@@ -233,63 +290,7 @@ void DrawLevelDriver2(const Vector3D& cameraPos, float cameraAngleY, const Volum
233290 CELL_OBJECT co;
234291 CDriver2LevelMap::UnpackCellObject (co, drawObjects[i].pco , drawObjects[i].nearCell );
235292
236- if (co.type >= MAX_MODELS)
237- {
238- // WHAT THE FUCK?
239- continue ;
240- }
241-
242- Vector3D absCellPosition = FromFixedVector (co.pos );
243- absCellPosition.y *= -1 .0f ;
244-
245- float distanceFromCamera = lengthSqr (absCellPosition - cameraPos);
246-
247- ModelRef_t* ref = GetModelCheckLods (co.type , distanceFromCamera);
248-
249- MODEL* model = ref->model ;
250-
251- float cellRotationRad = -co.yang / 64 .0f * PI_F * 2 .0f ;
252-
253- bool isGround = false ;
254-
255- if (model)
256- {
257- if (model->shape_flags & SHAPE_FLAG_SPRITE)
258- {
259- cellRotationRad = DEG2RAD (cameraAngleY);
260- }
261-
262- if ((model->shape_flags & (SHAPE_FLAG_WATER | SHAPE_FLAG_TILE)) ||
263- (model->flags2 & (MODEL_FLAG_PATH | MODEL_FLAG_GRASS)))
264- {
265- isGround = true ;
266- }
267- }
268-
269- Matrix4x4 objectMatrix = translate (absCellPosition) * rotateY4 (cellRotationRad);
270- GR_SetMatrix (MATRIX_WORLD, objectMatrix);
271- GR_UpdateMatrixUniforms ();
272-
273- if (isGround && g_nightMode)
274- CRenderModel::SetupLightingProperties (0 .35f , 0 .0f );
275- else
276- CRenderModel::SetupLightingProperties (1 .0f , 1 .0f );
277-
278- CRenderModel* renderModel = (CRenderModel*)ref->userData ;
279-
280- if (renderModel)
281- {
282- const float boundSphere = ref->model ->bounding_sphere * RENDER_SCALING * 2 .0f ;
283- if (frustrumVolume.IsSphereInside (absCellPosition, boundSphere))
284- {
285- renderModel->Draw ();
286- g_drawnModels++;
287- g_drawnPolygons += ref->model ->num_polys ;
288-
289- if (g_displayCollisionBoxes)
290- CRenderModel::DrawModelCollisionBox (ref, co.pos , co.yang );
291- }
292- }
293+ DrawCellObject (co, cameraPos, cameraAngleY, frustrumVolume, true );
293294 }
294295
295296 if (g_displayRoads)
@@ -304,38 +305,82 @@ void DrawLevelDriver2(const Vector3D& cameraPos, float cameraAngleY, const Volum
304305 sn = isin (straight->angle );
305306 cs = icos (straight->angle );
306307
307- VECTOR_NOPAD offset{ ((straight->length / 2 ) * sn) / ONE, 0 , ((straight->length / 2 ) * cs) / ONE };
308+ int numLanes = ROAD_WIDTH_IN_LANES (straight);
309+ for (int j = 0 ; j < numLanes; j++)
310+ {
311+ VECTOR_NOPAD offset{ ((straight->length / 2 ) * sn) / ONE, 0 , ((straight->length / 2 ) * cs) / ONE };
312+ VECTOR_NOPAD lane_offset{ ((512 * j - numLanes * 256 + 256 ) * -cs) / ONE, 0 , ((512 * j - numLanes * 256 + 256 ) * sn) / ONE };
313+
314+ VECTOR_NOPAD positionA{ straight->Midx - offset.vx + lane_offset.vx , 0 , straight->Midz - offset.vz + lane_offset.vz };
315+ VECTOR_NOPAD positionB{ straight->Midx + offset.vx + lane_offset.vx , 0 , straight->Midz + offset.vz + lane_offset.vz };
316+
317+ ColorRGBA color (0 .0f , 1 .0f , 0 .0f , 1 .0f );
318+
319+ if (ROAD_IS_PARKING_ALLOWED_AT (straight, j))
320+ {
321+ color.x = 0 .0f ;
322+ color.y = 1 .0f ;
323+ }
324+
325+ if (ROAD_LANE_DIR (straight, j))
326+ color.z = 1 .0f ;
308327
309- VECTOR_NOPAD positionA { straight->Midx - offset.vx , 0 , straight->Midz - offset.vz };
310- VECTOR_NOPAD positionB { straight->Midx + offset.vx , 0 , straight->Midz + offset.vz };
328+ if (!ROAD_IS_AI_LANE (straight, j))
329+ {
330+ color.x = 1 .0f ;
331+ color.y = 0 .0f ;
332+ color.w = 0 .5f ;
333+ }
311334
312- DebugOverlay_Line (FromFixedVector (positionA), FromFixedVector (positionB), ColorRGBA (1 ,1 ,0 ,1 ));
335+ DebugOverlay_Line (FromFixedVector (positionA), FromFixedVector (positionB), color);
336+ }
313337 }
314338
315339 for (int i = 0 ; i < levMapDriver2->GetNumCurves (); i++)
316340 {
317341 DRIVER2_CURVE* curve = levMapDriver2->GetCurve (i | 0x4000 );
318342
319- VECTOR_NOPAD positionA;
320- VECTOR_NOPAD positionB;
321-
322- int distAlongPath = curve->start ;
323- int curveLength = curve->end - curve->start & 4095 ;
343+ int numLanes = ROAD_WIDTH_IN_LANES (curve);
324344
325- for (int j = 0 ; j < 8 ; j++)
345+ for (int j = 0 ; j < numLanes ; j++)
326346 {
327- int angle = distAlongPath;
347+ VECTOR_NOPAD positionA;
348+ VECTOR_NOPAD positionB;
328349
329- int radius = curve->inside * 1024 + 512 * ROAD_LANES_COUNT (curve);
350+ int distAlongPath = curve->start ;
351+ int curveLength = curve->end - curve->start & 4095 ;
330352
331- positionB = VECTOR_NOPAD{ curve->Midx + (radius * isin (angle)) / ONE, 0 , curve->Midz + (radius * icos (angle)) / ONE };
353+ ColorRGBA color (0 .0f , 1 .0f , 0 .0f , 1 .0f );
354+
355+ if (ROAD_IS_PARKING_ALLOWED_AT (curve, j))
356+ {
357+ color.x = 0 .0f ;
358+ color.y = 1 .0f ;
359+ }
360+
361+ if (ROAD_LANE_DIR (curve, j))
362+ color.z = 1 .0f ;
363+
364+ if (!ROAD_IS_AI_LANE (curve, j))
365+ {
366+ color.x = 1 .0f ;
367+ color.y = 0 .0f ;
368+ color.w = 0 .5f ;
369+ }
370+
371+ for (int k = 0 ; k < 8 ; k++)
372+ {
373+ int radius = curve->inside * 1024 + 256 + 512 * j;
332374
333- distAlongPath += curveLength / 7 ; // 8 - 1
375+ positionB = VECTOR_NOPAD{ curve-> Midx + (radius * isin (distAlongPath)) / ONE, 0 , curve-> Midz + (radius * icos (distAlongPath)) / ONE };
334376
335- if (j > 0 )
336- DebugOverlay_Line (FromFixedVector (positionA), FromFixedVector (positionB), ColorRGBA (1 , 1 , 0 , 1 ));
377+ distAlongPath += curveLength / 7 ; // 8 - 1
337378
338- positionA = positionB;
379+ if (k > 0 )
380+ DebugOverlay_Line (FromFixedVector (positionA), FromFixedVector (positionB), color);
381+
382+ positionA = positionB;
383+ }
339384 }
340385 }
341386 }
@@ -444,63 +489,6 @@ void DrawLevelDriver1(const Vector3D& cameraPos, float cameraAngleY, const Volum
444489
445490 for (uint i = 0 ; i < drawObjects.size (); i++)
446491 {
447- pco = drawObjects[i];
448-
449- if (pco->type >= MAX_MODELS)
450- {
451- // WHAT THE FUCK?
452- continue ;
453- }
454-
455- Vector3D absCellPosition = FromFixedVector (pco->pos );
456- absCellPosition.y *= -1 .0f ;
457-
458- float distanceFromCamera = lengthSqr (absCellPosition - cameraPos);
459-
460- ModelRef_t* ref = GetModelCheckLods (pco->type , distanceFromCamera);
461- MODEL* model = ref->model ;
462-
463- float cellRotationRad = -pco->yang / 64 .0f * PI_F * 2 .0f ;
464-
465- bool isGround = false ;
466-
467- if (model)
468- {
469- if (model->shape_flags & SHAPE_FLAG_SPRITE)
470- {
471- cellRotationRad = DEG2RAD (cameraAngleY);
472- }
473-
474- if ((model->shape_flags & (SHAPE_FLAG_WATER | SHAPE_FLAG_TILE)) ||
475- (model->flags2 & (MODEL_FLAG_PATH | MODEL_FLAG_GRASS)))
476- {
477- isGround = true ;
478- }
479- }
480-
481- Matrix4x4 objectMatrix = translate (absCellPosition) * rotateY4 (cellRotationRad);
482- GR_SetMatrix (MATRIX_WORLD, objectMatrix);
483- GR_UpdateMatrixUniforms ();
484-
485- if (g_nightMode)
486- CRenderModel::SetupLightingProperties (0 .25f , 0 .0f );
487- else
488- CRenderModel::SetupLightingProperties (0 .55f , 0 .55f );
489-
490- CRenderModel* renderModel = (CRenderModel*)ref->userData ;
491-
492- if (renderModel)
493- {
494- const float boundSphere = ref->model ->bounding_sphere * RENDER_SCALING * 2 .0f ;
495- if (frustrumVolume.IsSphereInside (absCellPosition, boundSphere))
496- {
497- renderModel->Draw ();
498- g_drawnModels++;
499- g_drawnPolygons += ref->model ->num_polys ;
500-
501- if (g_displayCollisionBoxes)
502- CRenderModel::DrawModelCollisionBox (ref, pco->pos , pco->yang );
503- }
504- }
492+ DrawCellObject (*drawObjects[i], cameraPos, cameraAngleY, frustrumVolume, true );
505493 }
506494}
0 commit comments