/*
** Command & Conquer Generals(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
*/
////////////////////////////////////////////////////////////////////////////////
// //
// (c) 2001-2003 Electronic Arts Inc. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: W3DRoadBuffer.h //////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Westwood Studios Pacific.
//
// Confidential Information
// Copyright (C) 2001 - All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Project: RTS3
//
// File name: W3DRoadBuffer.h
//
// Created: John Ahlquist, May 2001
//
// Desc: Draw buffer to handle all the roads in a scene.
//
//-----------------------------------------------------------------------------
#pragma once
#ifndef __W3DROAD_BUFFER_H_
#define __W3DROAD_BUFFER_H_
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "always.h"
#include "rendobj.h"
#include "w3d_file.h"
#include "dx8vertexbuffer.h"
#include "dx8indexbuffer.h"
#include "shader.h"
#include "vertmaterial.h"
//#include "common/GameFileSystem.h"
#include "Common/FileSystem.h" // for LOAD_TEST_ASSETS
#include "Lib/BaseType.h"
#include "common/GameType.h"
#include "Common/AsciiString.h"
//-----------------------------------------------------------------------------
// Forward References
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Type Defines
//-----------------------------------------------------------------------------
enum {bottomLeft=0, bottomRight=1, topLeft=2, topRight=3, NUM_CORNERS=4};
#define MAX_LINKS 6
#define DEFAULT_ROAD_SCALE (8.0f)
#define MIN_ROAD_SEGMENT (0.25f)
struct TRoadPt
{
Vector2 loc;
Vector2 top;
Vector2 bottom;
Int count;
Bool last;
Bool multi;
Bool isAngled;
Bool isJoin;
};
struct TRoadSegInfo
{
Vector2 loc;
Vector2 roadNormal;
Vector2 roadVector;
Vector2 corners[NUM_CORNERS];
Real uOffset;
Real vOffset;
Real scale;
};
// The individual data for a road segment.
enum {MAX_SEG_VERTEX=500, MAX_SEG_INDEX=2000};
enum TCorner
{
SEGMENT,
CURVE,
TEE,
FOUR_WAY,
THREE_WAY_Y,
THREE_WAY_H,
THREE_WAY_H_FLIP,
ALPHA_JOIN,
NUM_JOINS
};
class RoadSegment
{
public:
TRoadPt m_pt1; ///< Drawing location pt1 to pt2.
TRoadPt m_pt2; ///< Drawing location to.
Real m_curveRadius; ///< Radius if it is a curve.
TCorner m_type; ///< Segment, or curve, or intersection.
Real m_scale; ///< Scale.
Real m_widthInTexture; ///< Width of the road in the texture.
Int m_uniqueID; ///< Road type.
protected:
Int m_numVertex;
VertexFormatXYZDUV1* m_vb;
Int m_numIndex;
UnsignedShort* m_ib;
TRoadSegInfo m_info;
SphereClass m_bounds;
public:
RoadSegment(void);
~RoadSegment(void);
public:
void SetVertexBuffer(VertexFormatXYZDUV1 *vb, Int numVertex);
void SetIndexBuffer(UnsignedShort *ib, Int numIndex);
void SetRoadSegInfo(TRoadSegInfo *pInfo) {m_info = *pInfo;};
void GetRoadSegInfo(TRoadSegInfo *pInfo) {*pInfo = m_info;};
const SphereClass &getBounds(void) {return m_bounds;};
Int GetNumVertex(void) {return m_numVertex;};
Int GetNumIndex(void) {return m_numIndex;};
Int GetVertices(VertexFormatXYZDUV1 *destination_vb, Int numToCopy);
Int GetIndices(UnsignedShort *destination_ib, Int numToCopy, Int offset);
void updateSegLighting(void);
} ;
class RoadType {
public:
RoadType(void);
~RoadType(void);
protected:
TextureClass *m_roadTexture; ///m_pt1; pRoad->m_pt1 = pRoad->m_pt2; pRoad->m_pt2 = tmp;}; ///< Flips the loc1 and loc2 info.
void insertCurveSegmentAt(Int ndx1, Int ndx2);
void insertCrossTypeJoins(void);
void insertJoinAt(Int ndx);
void miter(Int ndx1, Int ndx2);
void moveRoadSegTo(Int fromNdx, Int toNdx);
void checkLinkAfter(Int ndx);
void checkLinkBefore(Int ndx);
void updateCounts(RoadSegment *pRoad);
void updateCountsAndFlags(void);
void insertCurveSegments(void);
void insertTeeIntersections(void);
void insertTee(Vector2 loc, Int index1, Real scale);
Bool insertY(Vector2 loc, Int index1, Real scale);
void insert4Way(Vector2 loc, Int index1, Real scale);
void offset4Way(TRoadPt *pc1, TRoadPt *pc2, TRoadPt *pc3, TRoadPt *pr3, TRoadPt *pc4, Vector2 loc, Vector2 alignVector, Real widthInTexture);
void offset3Way(TRoadPt *pc1, TRoadPt *pc2, TRoadPt *pc3, Vector2 loc, Vector2 upVector, Vector2 teeVector, Real widthInTexture);
void offsetY(TRoadPt *pc1, TRoadPt *pc2, TRoadPt *pc3, Vector2 loc, Vector2 upVector, Real widthInTexture);
void offsetH(TRoadPt *pc1, TRoadPt *pc2, TRoadPt *pc3, Vector2 loc, Vector2 upVector, Vector2 teeVector, Bool flip, Bool mirror, Real widthInTexture);
void preloadRoadsInVertexAndIndexBuffers(void); ///< Fills the index and vertex buffers for drawing.
void preloadRoadSegment(RoadSegment *pRoad); ///< Fills the index and vertex buffers for drawing 1 segment.
void loadCurve(RoadSegment *pRoad, Vector2 loc1, Vector2 loc2, Real scale); ///< Fills the index and vertex buffers for drawing 1 fade.
void loadTee(RoadSegment *pRoad, Vector2 loc1, Vector2 loc2, Bool is4way, Real scale); ///< Fills the index and vertex buffers for drawing 1 tee intersection.
void loadY(RoadSegment *pRoad, Vector2 loc1, Vector2 loc2, Real scale); ///< Fills the index and vertex buffers for drawing 1 Y intersection.
void loadAlphaJoin(RoadSegment *pRoad, Vector2 loc1, Vector2 loc2, Real scale); ///< Fills the index and vertex buffers for drawing 1 alpha blend cap.
void loadH(RoadSegment *pRoad, Vector2 loc1, Vector2 loc2, Bool flip, Real scale); ///< Fills the index and vertex buffers for drawing 1 h tee intersection.
void loadFloatSection(RoadSegment *pRoad, Vector2 loc,
Vector2 roadVector, Real height, Real left, Real right, Real uOffset, Real vOffset, Real scale);
void loadFloat4PtSection(RoadSegment *pRoad, Vector2 loc,
Vector2 roadNormal, Vector2 roadVector,
Vector2 *cornersP,
Real uOffset, Real vOffset, Real uScale, Real vScale);
void loadLit4PtSection(RoadSegment *pRoad, UnsignedShort *ib, VertexFormatXYZDUV1 *vb, RefRenderObjListIterator *pDynamicLightsIterator);
void loadRoadsInVertexAndIndexBuffers(void); ///< Fills the index and vertex buffers for drawing.
void loadLitRoadsInVertexAndIndexBuffers(RefRenderObjListIterator *pDynamicLightsIterator); ///< Fills the index and vertex buffers for drawing.
void loadRoadSegment(UnsignedShort *ib, VertexFormatXYZDUV1 *vb, RoadSegment *pRoad); ///< Fills the index and vertex buffers for drawing 1 segment.
void allocateRoadBuffers(void); ///< Allocates the buffers.
void freeRoadBuffers(void); ///< Frees the index and vertex buffers.
void rotateAbout(Vector2 *ptP, Vector2 center, Real angle);
};
#endif // end __W3DROAD_BUFFER_H_