2025-08-17 13:14:17 -04:00
|
|
|
#include "xclipmap.h"
|
|
|
|
|
|
|
|
|
|
XClipMap::XClipMap()
|
2025-09-07 12:36:08 -04:00
|
|
|
: XAsset()
|
|
|
|
|
, mName()
|
|
|
|
|
, mIsInUse(false)
|
|
|
|
|
, mPlaneCount(0)
|
|
|
|
|
, mPlanes()
|
|
|
|
|
, mNumStaticModels(0)
|
|
|
|
|
, mStaticModelList()
|
|
|
|
|
, mNumMaterials(0)
|
|
|
|
|
, mMaterials()
|
|
|
|
|
, mNumBrushSides(0)
|
|
|
|
|
, mBrushsides()
|
|
|
|
|
, mNumBrushEdges(0)
|
|
|
|
|
, mBrushEdges()
|
|
|
|
|
, mNumNodes(0)
|
|
|
|
|
, mNodes()
|
|
|
|
|
, mNumLeafs(0)
|
|
|
|
|
, mLeafs()
|
|
|
|
|
, mLeafBrushNodesCount(0)
|
|
|
|
|
, mLeafBrushNodes()
|
|
|
|
|
, mNumLeafBrushes(0)
|
|
|
|
|
, mLeafBrushes()
|
|
|
|
|
, mNumLeafSurfaces(0)
|
|
|
|
|
, mLeafSurfaces()
|
|
|
|
|
, mVertCount(0)
|
|
|
|
|
, mVerts()
|
|
|
|
|
, mTriCount(0)
|
|
|
|
|
, mTriIndices()
|
|
|
|
|
, mTriEdgeIsWalkable()
|
|
|
|
|
, mBorderCount(0)
|
|
|
|
|
, mBorders()
|
|
|
|
|
, mPartitionCount(0)
|
|
|
|
|
, mPartitions()
|
|
|
|
|
, mAabbTreeCount(0)
|
|
|
|
|
, mAabbTrees()
|
|
|
|
|
, mNumSubModels(0)
|
|
|
|
|
, mCModels()
|
|
|
|
|
, mNumBrushes(0)
|
|
|
|
|
, mBrushes()
|
|
|
|
|
, mNumClusters(0)
|
|
|
|
|
, mClusterBytes(0)
|
|
|
|
|
, mVisibility()
|
|
|
|
|
, mVised(0)
|
|
|
|
|
, mMapEnts()
|
|
|
|
|
, mBoxBrush()
|
|
|
|
|
, mBoxModel()
|
|
|
|
|
, mDynEntCounts(0)
|
|
|
|
|
, mDynEntDefList(2)
|
|
|
|
|
, mDynEntPoseList(2)
|
|
|
|
|
, mDynEntClientList(2)
|
|
|
|
|
, mDynEntCollList(2)
|
|
|
|
|
, mChecksum(0)
|
|
|
|
|
{
|
2025-09-05 18:35:17 -04:00
|
|
|
SetType(ASSET_TYPE_CLIPMAP);
|
2025-09-10 21:58:26 -04:00
|
|
|
SetName("Clip Map");
|
2025-08-17 13:14:17 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
void XClipMap::ParseData(XDataStream *aStream)
|
2025-09-07 12:36:08 -04:00
|
|
|
{
|
|
|
|
|
if (GetPtr() == -1)
|
|
|
|
|
{
|
2025-09-10 21:58:26 -04:00
|
|
|
// name / header
|
2025-09-07 12:36:08 -04:00
|
|
|
mName.ParsePtr(aStream, false);
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
mIsInUse = aStream->ParseUInt32(QString("%1 is in use").arg(GetName()));
|
|
|
|
|
mPlaneCount = aStream->ParseInt32 (QString("%1 plane count").arg(GetName()));
|
|
|
|
|
qint32 planePtr = aStream->ParseInt32(QString("%1 plane ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
// static models / materials / brushes
|
|
|
|
|
mNumStaticModels = aStream->ParseUInt32(QString("%1 num static models").arg(GetName()));
|
|
|
|
|
qint32 staticModelPtr = aStream->ParseInt32(QString("%1 static model ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumMaterials = aStream->ParseUInt32(QString("%1 num materials").arg(GetName()));
|
|
|
|
|
qint32 materialsPtr = aStream->ParseInt32(QString("%1 materials ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumBrushSides = aStream->ParseUInt32(QString("%1 num brush sides").arg(GetName()));
|
|
|
|
|
qint32 brushSidesPtr = aStream->ParseInt32(QString("%1 brush sides ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumBrushEdges = aStream->ParseUInt32(QString("%1 num brush edges").arg(GetName()));
|
|
|
|
|
qint32 brushEdgesPtr = aStream->ParseInt32(QString("%1 brush edges ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumNodes = aStream->ParseUInt32(QString("%1 num nodes").arg(GetName()));
|
|
|
|
|
qint32 nodesPtr = aStream->ParseInt32(QString("%1 nodes ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumLeafs = aStream->ParseUInt32(QString("%1 num leafs").arg(GetName()));
|
|
|
|
|
qint32 leafsPtr = aStream->ParseInt32(QString("%1 leafs ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mLeafBrushNodesCount = aStream->ParseUInt32(QString("%1 leaf brush nodes count").arg(GetName()));
|
|
|
|
|
qint32 leafsBrushNodesPtr= aStream->ParseInt32(QString("%1 leaf brush nodes ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumLeafBrushes = aStream->ParseUInt32(QString("%1 num leaf brushes").arg(GetName()));
|
|
|
|
|
qint32 leafBrushesPtr = aStream->ParseInt32(QString("%1 leaf brushes ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumLeafSurfaces = aStream->ParseUInt32(QString("%1 num leaf surfaces").arg(GetName()));
|
|
|
|
|
qint32 leafSurfacesPtr = aStream->ParseInt32(QString("%1 leaf surfaces ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mVertCount = aStream->ParseUInt32(QString("%1 vert count").arg(GetName()));
|
|
|
|
|
qint32 vertPtr = aStream->ParseInt32(QString("%1 vert ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mTriCount = aStream->ParseInt32(QString("%1 tri count").arg(GetName()));
|
|
|
|
|
qint32 triIndicesPtr = aStream->ParseInt32(QString("%1 tri indices ptr").arg(GetName()));
|
|
|
|
|
qint32 triEdgeWalkablePtr= aStream->ParseInt32(QString("%1 tri edge walkable ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mBorderCount = aStream->ParseInt32(QString("%1 border count").arg(GetName()));
|
|
|
|
|
qint32 bordersPtr = aStream->ParseInt32(QString("%1 borders ptr").arg(GetName()));
|
2025-09-07 12:36:08 -04:00
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
mPartitionCount = aStream->ParseInt32(QString("%1 partition count").arg(GetName()));
|
|
|
|
|
qint32 partitionsPtr = aStream->ParseInt32(QString("%1 partitions ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mAabbTreeCount = aStream->ParseInt32(QString("%1 aabb tree count").arg(GetName()));
|
|
|
|
|
qint32 aabbTreesPtr = aStream->ParseInt32(QString("%1 aabb trees ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumSubModels = aStream->ParseUInt32(QString("%1 num sub models").arg(GetName()));
|
|
|
|
|
qint32 cModelsPtr = aStream->ParseInt32(QString("%1 c models ptr").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
mNumBrushes = aStream->ParseUInt32(QString("%1 num brushes").arg(GetName()));
|
|
|
|
|
|
|
|
|
|
// skip padding
|
2025-09-07 12:36:08 -04:00
|
|
|
aStream->skipRawData(2);
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
// visibility + ents
|
|
|
|
|
qint32 brushesPtr = aStream->ParseInt32(QString("%1 brushes ptr").arg(GetName()));
|
|
|
|
|
mNumClusters = aStream->ParseInt32(QString("%1 num clusters").arg(GetName()));
|
|
|
|
|
mClusterBytes = aStream->ParseInt32(QString("%1 cluster bytes").arg(GetName()));
|
|
|
|
|
qint32 visibilityPtr = aStream->ParseInt32(QString("%1 visibility ptr").arg(GetName()));
|
|
|
|
|
mVised = aStream->ParseInt32(QString("%1 vised").arg(GetName()));
|
|
|
|
|
qint32 mapEntsPtr = aStream->ParseInt32(QString("%1 map ents ptr").arg(GetName()));
|
2025-09-07 23:11:48 -04:00
|
|
|
|
|
|
|
|
mMapEnts.ParsePtr(aStream, false);
|
|
|
|
|
mBoxBrush.ParsePtr(aStream, false);
|
2025-09-07 12:36:08 -04:00
|
|
|
mBoxModel.ParseData(aStream);
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
// dynEnt counts
|
2025-09-07 12:36:08 -04:00
|
|
|
quint16 dynEntCount;
|
2025-09-10 21:58:26 -04:00
|
|
|
dynEntCount = aStream->ParseUInt16(QString("%1 dyn ent count [0]").arg(GetName()));
|
2025-09-07 12:36:08 -04:00
|
|
|
mDynEntCounts.append(dynEntCount);
|
2025-09-10 21:58:26 -04:00
|
|
|
dynEntCount = aStream->ParseUInt16(QString("%1 dyn ent count [1]").arg(GetName()));
|
2025-09-07 12:36:08 -04:00
|
|
|
mDynEntCounts.append(dynEntCount);
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
// dynEnt lists (ParsePtr once each)
|
2025-09-07 12:36:08 -04:00
|
|
|
mDynEntDefList[0].ParsePtr(aStream, false);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntDefList[1].ParsePtr(aStream, false);
|
2025-09-07 12:36:08 -04:00
|
|
|
|
|
|
|
|
mDynEntPoseList[0].ParsePtr(aStream, false);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntPoseList[1].ParsePtr(aStream, false);
|
2025-09-07 12:36:08 -04:00
|
|
|
|
|
|
|
|
mDynEntClientList[0].ParsePtr(aStream, false);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntClientList[1].ParsePtr(aStream, false);
|
2025-09-07 12:36:08 -04:00
|
|
|
|
|
|
|
|
mDynEntCollList[0].ParsePtr(aStream, false);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntCollList[1].ParsePtr(aStream, false);
|
2025-09-07 12:36:08 -04:00
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
mChecksum = aStream->ParseUInt32(QString("%1 checksum").arg(GetName()));
|
2025-09-07 12:36:08 -04:00
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
// =====================
|
|
|
|
|
// Sectioned data blocks
|
|
|
|
|
// =====================
|
|
|
|
|
if (planePtr) {
|
|
|
|
|
for (int i = 0; i < mPlaneCount; i++) {
|
2025-09-07 12:36:08 -04:00
|
|
|
XCPlane newCPlane;
|
|
|
|
|
newCPlane.ParseData(aStream);
|
|
|
|
|
mPlanes.append(newCPlane);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (staticModelPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumStaticModels; i++) {
|
2025-09-07 12:36:08 -04:00
|
|
|
XCStaticModel newModel;
|
|
|
|
|
newModel.ParseData(aStream);
|
|
|
|
|
mStaticModelList.append(newModel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (materialsPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumMaterials; i++) {
|
|
|
|
|
XDMaterial newMat;
|
|
|
|
|
newMat.ParseData(aStream);
|
|
|
|
|
mMaterials.append(newMat);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (brushSidesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumBrushSides; i++) {
|
|
|
|
|
XCBrushSide newSide;
|
|
|
|
|
newSide.ParseData(aStream);
|
|
|
|
|
mBrushsides.append(newSide);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (brushEdgesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumBrushEdges; i++) {
|
|
|
|
|
quint8 edge = aStream->ParseUInt8(QString("%1 edge %2").arg(GetName()).arg(i));
|
|
|
|
|
mBrushEdges.append(edge);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (nodesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumNodes; i++) {
|
2025-09-07 12:36:08 -04:00
|
|
|
XCNode newNode;
|
|
|
|
|
newNode.ParseData(aStream);
|
|
|
|
|
mNodes.append(newNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (leafsPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumLeafs; i++) {
|
2025-09-07 12:36:08 -04:00
|
|
|
XCLeaf newLeaf;
|
|
|
|
|
newLeaf.ParseData(aStream);
|
|
|
|
|
mLeafs.append(newLeaf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (leafBrushesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumLeafBrushes; i++) {
|
|
|
|
|
quint32 brush = aStream->ParseUInt32(QString("%1 brush %2").arg(GetName()).arg(i));
|
|
|
|
|
mLeafBrushes.append(brush);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
|
|
|
|
}
|
2025-08-17 13:14:17 -04:00
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (leafsBrushNodesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mLeafBrushNodesCount; i++) {
|
|
|
|
|
XCLeafBrushNode newNode;
|
|
|
|
|
newNode.ParseData(aStream);
|
|
|
|
|
mLeafBrushNodes.append(newNode);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
|
|
|
|
}
|
2025-08-17 13:14:17 -04:00
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (leafSurfacesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumLeafSurfaces; i++) {
|
|
|
|
|
quint32 surf = aStream->ParseUInt32(QString("%1 surf %2").arg(GetName()).arg(i));
|
|
|
|
|
mLeafSurfaces.append(surf);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (vertPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mVertCount; i++) {
|
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
|
QVector3D v;
|
|
|
|
|
v[j] = aStream->ParseSingle(QString("%1 vert (%2, %3)").arg(GetName()).arg(i).arg(j));
|
|
|
|
|
mVerts.append(v);
|
|
|
|
|
}
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (triIndicesPtr) {
|
|
|
|
|
for (int i = 0; i < mTriCount; i++) {
|
|
|
|
|
quint32 tri = aStream->ParseUInt32(QString("%1 tri %2").arg(GetName()).arg(i));
|
|
|
|
|
mTriIndices.append(tri);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (triEdgeWalkablePtr) {
|
|
|
|
|
aStream->readRawData(mTriEdgeIsWalkable.data(),
|
|
|
|
|
((3 * mTriCount + 31) >> 3) & 0xFFFFFFFC);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (bordersPtr) {
|
|
|
|
|
for (int i = 0; i < mBorderCount; i++) {
|
|
|
|
|
XCollisionBorder b;
|
|
|
|
|
b.ParseData(aStream);
|
|
|
|
|
mBorders.append(b);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (partitionsPtr) {
|
|
|
|
|
for (int i = 0; i < mPartitionCount; i++) {
|
|
|
|
|
XCollisionPartition p;
|
|
|
|
|
p.ParseData(aStream);
|
|
|
|
|
mPartitions.append(p);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (aabbTreesPtr) {
|
|
|
|
|
for (int i = 0; i < mAabbTreeCount; i++) {
|
|
|
|
|
XCollisionAabbTree t;
|
|
|
|
|
t.ParseData(aStream);
|
|
|
|
|
mAabbTrees.append(t);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (cModelsPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumSubModels; i++) {
|
|
|
|
|
XCModel m;
|
|
|
|
|
m.ParseData(aStream);
|
|
|
|
|
mCModels.append(m);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (brushesPtr) {
|
|
|
|
|
for (quint32 i = 0; i < mNumBrushes; i++) {
|
|
|
|
|
XCBrush b;
|
|
|
|
|
b.ParseData(aStream);
|
|
|
|
|
mBrushes.append(b);
|
2025-09-07 23:11:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (visibilityPtr) {
|
2025-09-07 23:11:48 -04:00
|
|
|
aStream->readRawData(mVisibility.data(), mClusterBytes * mNumClusters);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
if (mapEntsPtr) {
|
2025-09-07 23:11:48 -04:00
|
|
|
mMapEnts.ParseData(aStream);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
// box brush / dynEnt blocks
|
2025-09-07 23:11:48 -04:00
|
|
|
mBoxBrush.ParseData(aStream);
|
|
|
|
|
|
|
|
|
|
mDynEntDefList[0].ParseData(aStream);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntDefList[1].ParseData(aStream);
|
2025-09-07 23:11:48 -04:00
|
|
|
|
|
|
|
|
mDynEntPoseList[0].ParseData(aStream);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntPoseList[1].ParseData(aStream);
|
2025-09-07 23:11:48 -04:00
|
|
|
|
|
|
|
|
mDynEntClientList[0].ParseData(aStream);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntClientList[1].ParseData(aStream);
|
2025-09-07 23:11:48 -04:00
|
|
|
|
|
|
|
|
mDynEntCollList[0].ParseData(aStream);
|
2025-09-10 21:58:26 -04:00
|
|
|
mDynEntCollList[1].ParseData(aStream);
|
2025-09-07 12:36:08 -04:00
|
|
|
}
|
2025-08-17 13:14:17 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-10 21:58:26 -04:00
|
|
|
|
2025-09-05 18:35:17 -04:00
|
|
|
void XClipMap::Clear()
|
|
|
|
|
{
|
2025-08-17 13:14:17 -04:00
|
|
|
|
|
|
|
|
}
|