714 lines
18 KiB
C++
714 lines
18 KiB
C++
#include "stdafx.h"
|
|
#include "editpat.h"
|
|
#include "nel/misc/time_nl.h"
|
|
|
|
using namespace NLMISC;
|
|
|
|
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
#define DBGWELD_DUMPx
|
|
#define DBGWELD_ACTIONx
|
|
#define DBG_NAMEDSELSx
|
|
|
|
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
class EPVertMapRestore : public RestoreObj
|
|
{
|
|
public:
|
|
BOOL gotRedo;
|
|
EPVertMapper undo;
|
|
EPVertMapper redo;
|
|
EditPatchData *epd;
|
|
|
|
EPVertMapRestore(EditPatchData *d)
|
|
{
|
|
undo = d->vertMap;
|
|
epd = d;
|
|
gotRedo = FALSE;
|
|
}
|
|
|
|
void Restore(int isUndo)
|
|
{
|
|
if (!gotRedo)
|
|
{
|
|
gotRedo = TRUE;
|
|
redo = epd->vertMap;
|
|
}
|
|
epd->vertMap = undo;
|
|
}
|
|
|
|
void Redo()
|
|
{
|
|
epd->vertMap = redo;
|
|
}
|
|
|
|
int Size() { return 1; }
|
|
void EndHold() { }
|
|
TSTR Description() { return TSTR(_T("EPVertMapRestore")); }
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
class FinalPatchRestore : public RestoreObj
|
|
{
|
|
public:
|
|
BOOL gotRedo;
|
|
PatchMesh undo;
|
|
PatchMesh redo;
|
|
PatchMesh *patch;
|
|
RPatchMesh *rundo;
|
|
RPatchMesh *rredo;
|
|
RPatchMesh *rpatch;
|
|
|
|
FinalPatchRestore(PatchMesh *s, RPatchMesh *rs)
|
|
{
|
|
rundo = NULL;
|
|
rredo = NULL;
|
|
|
|
undo = *s;
|
|
|
|
if (rs)
|
|
{
|
|
rundo=new RPatchMesh();
|
|
*rundo = *rs;
|
|
}
|
|
|
|
patch = s;
|
|
rpatch = rs;
|
|
gotRedo = FALSE;
|
|
}
|
|
|
|
virtual ~FinalPatchRestore()
|
|
{
|
|
if (rundo)
|
|
delete rundo;
|
|
if (rredo)
|
|
delete rredo;
|
|
}
|
|
|
|
void Restore(int isUndo)
|
|
{
|
|
if (!gotRedo)
|
|
{
|
|
gotRedo = TRUE;
|
|
redo = *patch;
|
|
|
|
if (rpatch)
|
|
{
|
|
if (rredo==NULL)
|
|
rredo=new RPatchMesh();
|
|
|
|
*rredo = *rpatch;
|
|
}
|
|
}
|
|
*patch = undo;
|
|
|
|
if (rundo)
|
|
*rpatch = *rundo;
|
|
}
|
|
|
|
void Redo()
|
|
{
|
|
*patch = redo;
|
|
|
|
if (rredo)
|
|
*rpatch = *rredo;
|
|
}
|
|
|
|
int Size() { return 1; }
|
|
void EndHold() { }
|
|
TSTR Description() { return TSTR(_T("FinalPatchRestore")); }
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
EditPatchData::EditPatchData(EditPatchMod *mod)
|
|
{
|
|
meshSteps = mod->meshSteps;
|
|
// 3-18-99 to suport render steps and removal of the mental tesselator
|
|
meshStepsRender = mod->meshStepsRender;
|
|
showInterior = mod->showInterior;
|
|
|
|
// meshAdaptive = mod->meshAdaptive; // Future use (Not used now)
|
|
viewTess = mod->viewTess;
|
|
prodTess = mod->prodTess;
|
|
dispTess = mod->dispTess;
|
|
tileLevel = mod->tileLevel;
|
|
tileMode = mod->tileMode;
|
|
includeMeshes = mod->includeMeshes;
|
|
transitionType = mod->transitionType;
|
|
keepMapping = mod->keepMapping;
|
|
mViewTessNormals = mod->mViewTessNormals;
|
|
mProdTessNormals = mod->mProdTessNormals;
|
|
mViewTessWeld = mod->mViewTessWeld;
|
|
mProdTessWeld = mod->mProdTessWeld;
|
|
displayLattice = mod->displayLattice;
|
|
displaySurface = mod->displaySurface;
|
|
flags = 0;
|
|
tempData = NULL;
|
|
}
|
|
|
|
EditPatchData::EditPatchData(EditPatchData& emc)
|
|
{
|
|
meshSteps = emc.meshSteps;
|
|
// 3-18-99 to suport render steps and removal of the mental tesselator
|
|
meshStepsRender = emc.meshStepsRender;
|
|
showInterior = emc.showInterior;
|
|
|
|
// meshAdaptive = emc.meshAdaptive; // Future use (Not used now)
|
|
viewTess = emc.viewTess;
|
|
prodTess = emc.prodTess;
|
|
dispTess = emc.dispTess;
|
|
tileLevel = emc.tileLevel;
|
|
transitionType = emc.transitionType;
|
|
tileMode = emc.tileMode;
|
|
includeMeshes = emc.includeMeshes;
|
|
keepMapping = emc.keepMapping;
|
|
mViewTessNormals = emc.mViewTessNormals;
|
|
mProdTessNormals = emc.mProdTessNormals;
|
|
mViewTessWeld = emc.mViewTessWeld;
|
|
mProdTessWeld = emc.mProdTessWeld;
|
|
displayLattice = emc.displayLattice;
|
|
displaySurface = emc.displaySurface;
|
|
flags = emc.flags;
|
|
tempData = NULL;
|
|
vertMap = emc.vertMap;
|
|
finalPatch = emc.finalPatch;
|
|
rfinalPatch = emc.rfinalPatch;
|
|
}
|
|
|
|
void EditPatchData::Apply(TimeValue t, RPO *patchOb, int selLevel)
|
|
{
|
|
TTicks ticks=CTime::getPerformanceTime ();
|
|
// Either just copy it from the existing cache or rebuild from previous level!
|
|
if (!GetFlag(EPD_UPDATING_CACHE) && tempData
|
|
&& tempData->PatchCached(t))
|
|
{
|
|
RPatchMesh *rpatch;
|
|
PatchMesh *patch=tempData->GetPatch(t, rpatch);
|
|
patchOb->patch.DeepCopy( patch,
|
|
PART_GEOM | SELECT_CHANNEL | PART_SUBSEL_TYPE|
|
|
PART_DISPLAY | PART_TOPO | TEXMAP_CHANNEL);
|
|
//rpatch->UpdateBinding (*patch, t);
|
|
*patchOb->rpatch=*rpatch;
|
|
patchOb->PointsWereChanged();
|
|
}
|
|
else if (GetFlag(EPD_HASDATA))
|
|
{
|
|
// For old files, which contain exhaustive data to reconstruct the editing process
|
|
// of patches, we'll have data in the 'changes' table. If it's there, go ahead and
|
|
// replay the edits, then store the alterations in our new delta format and discard
|
|
// the change table!
|
|
int count = changes.Count();
|
|
if (count)
|
|
{
|
|
// DebugPrint("*** Applying old style (%d) ***\n", count);
|
|
// Store the topology for future reference
|
|
vertMap.Build(patchOb->patch);
|
|
finalPatch = patchOb->patch;
|
|
rfinalPatch = *patchOb->rpatch;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
PModRecord *rec = changes[i];
|
|
// Record the topo flags
|
|
RecordTopologyTags(&patchOb->patch);
|
|
BOOL result = rec->Redo(&patchOb->patch, patchOb->rpatch, 0);
|
|
UpdateChanges(&patchOb->patch, patchOb->rpatch);
|
|
// If we hit one that didn't play back OK, we need to flush the remainder
|
|
if (!result)
|
|
{
|
|
for (int j = i; j < count; ++j)
|
|
delete changes[j];
|
|
changes.Delete(i, count - i);
|
|
break;
|
|
}
|
|
}
|
|
// Nuke the changes table
|
|
count = changes.Count();
|
|
for (int k = 0; k < count; ++k)
|
|
delete changes[k];
|
|
changes.Delete(0, count);
|
|
changes.Shrink();
|
|
count = 0;
|
|
}
|
|
else
|
|
{
|
|
// Apply deltas to incoming shape, placing into finalPatch
|
|
vertMap.UpdateAndApplyDeltas(patchOb->patch, finalPatch);
|
|
patchOb->patch = finalPatch;
|
|
*patchOb->rpatch = rfinalPatch;
|
|
}
|
|
patchOb->PointsWereChanged();
|
|
// Kind of a waste when there's no animation...
|
|
patchOb->UpdateValidity(GEOM_CHAN_NUM, FOREVER);
|
|
patchOb->UpdateValidity(TOPO_CHAN_NUM, FOREVER);
|
|
patchOb->UpdateValidity(SELECT_CHAN_NUM, FOREVER);
|
|
patchOb->UpdateValidity(SUBSEL_TYPE_CHAN_NUM, FOREVER);
|
|
patchOb->UpdateValidity(DISP_ATTRIB_CHAN_NUM, FOREVER);
|
|
}
|
|
else
|
|
{ // No data yet -- Store initial required data
|
|
// DebugPrint("<<<Storing Initial Data>>>\n");
|
|
vertMap.Build(patchOb->patch);
|
|
finalPatch = patchOb->patch;
|
|
rfinalPatch = *patchOb->rpatch;
|
|
}
|
|
|
|
// Hand it its mesh interpolation info
|
|
patchOb->SetMeshSteps(meshSteps);
|
|
// 3-18-99 to suport render steps and removal of the mental tesselator
|
|
patchOb->SetMeshStepsRender(meshStepsRender);
|
|
patchOb->SetShowInterior(showInterior);
|
|
|
|
// patchOb->SetAdaptive(meshAdaptive); // Future use (Not used now)
|
|
patchOb->SetViewTess(viewTess);
|
|
patchOb->SetProdTess(prodTess);
|
|
patchOb->SetDispTess(dispTess);
|
|
patchOb->rpatch->rTess.ModeTile=tileMode;
|
|
patchOb->rpatch->rTess.TileTesselLevel=tileLevel;
|
|
patchOb->rpatch->rTess.TransitionType=transitionType;
|
|
patchOb->rpatch->rTess.KeepMapping=keepMapping;
|
|
patchOb->SetViewTessNormals(mViewTessNormals);
|
|
patchOb->SetProdTessNormals(mProdTessNormals);
|
|
patchOb->SetViewTessWeld(mViewTessWeld);
|
|
patchOb->SetProdTessWeld(mProdTessWeld);
|
|
|
|
patchOb->showMesh = displaySurface;
|
|
patchOb->SetShowLattice(displayLattice);
|
|
patchOb->patch.dispFlags = 0; // TH 3/3/99
|
|
switch (selLevel)
|
|
{
|
|
case EP_PATCH:
|
|
patchOb->patch.SetDispFlag(DISP_SELPATCHES);
|
|
break;
|
|
case EP_EDGE:
|
|
patchOb->patch.SetDispFlag(DISP_SELEDGES);
|
|
break;
|
|
case EP_VERTEX:
|
|
patchOb->patch.SetDispFlag(DISP_VERTTICKS | DISP_SELVERTS | DISP_VERTS);
|
|
break;
|
|
case EP_TILE:
|
|
//patchOb->patch.SetDispFlag(DISP_VERTTICKS | DISP_SELVERTS | DISP_VERTS);
|
|
break;
|
|
}
|
|
patchOb->patch.selLevel = patchLevel[selLevel];
|
|
patchOb->rpatch->SetSelLevel (selLevel);
|
|
|
|
/*rfinalPatch.UpdateBinding (finalPatch, t);
|
|
patchOb->rpatch->UpdateBinding (patchOb->patch, t);*/
|
|
|
|
if (GetFlag(EPD_UPDATING_CACHE))
|
|
{
|
|
nlassert(tempData);
|
|
tempData->UpdateCache(patchOb);
|
|
SetFlag(EPD_UPDATING_CACHE, FALSE);
|
|
}
|
|
ticks=CTime::getPerformanceTime ()-ticks;
|
|
nldebug ("%f", CTime::ticksToSecond(ticks));
|
|
}
|
|
|
|
void EditPatchData::Invalidate(PartID part, BOOL patchValid)
|
|
{
|
|
if (tempData)
|
|
{
|
|
tempData->Invalidate(part, patchValid);
|
|
}
|
|
}
|
|
|
|
void EditPatchData::BeginEdit(TimeValue t)
|
|
{
|
|
nlassert(tempData);
|
|
if (!GetFlag(EPD_HASDATA))
|
|
SetFlag(EPD_HASDATA, TRUE);
|
|
}
|
|
|
|
EPTempData *EditPatchData::TempData(EditPatchMod *mod)
|
|
{
|
|
if (!tempData)
|
|
{
|
|
nlassert(mod->ip);
|
|
tempData = new EPTempData(mod, this);
|
|
}
|
|
return tempData;
|
|
}
|
|
|
|
void EditPatchData::RescaleWorldUnits(float f)
|
|
{
|
|
// Scale the deltas inside the vertex map
|
|
vertMap.RescaleWorldUnits(f);
|
|
// Now rescale stuff inside our data structures
|
|
Matrix3 stm = ScaleMatrix(Point3(f, f, f));
|
|
finalPatch.Transform(stm);
|
|
}
|
|
|
|
void EditPatchData::RecordTopologyTags(PatchMesh *patch)
|
|
{
|
|
// First, stuff all -1's into aux fields
|
|
int i;
|
|
for (i = 0; i < patch->numVerts; ++i)
|
|
patch->verts[i].aux1 = 0xffffffff;
|
|
for (i = 0; i < patch->numVecs; ++i)
|
|
patch->vecs[i].aux1 = 0xffffffff;
|
|
for (i = 0; i < patch->numPatches; ++i)
|
|
patch->patches[i].aux1 = 0xffffffff;
|
|
// Now put in our tags
|
|
vertMap.RecordTopologyTags(*patch);
|
|
}
|
|
|
|
GenericNamedSelSetList &EditPatchData::GetSelSet(EditPatchMod *mod)
|
|
{
|
|
switch (mod->GetSubobjectLevel())
|
|
{
|
|
case EP_VERTEX:
|
|
return vselSet;
|
|
case EP_EDGE:
|
|
return eselSet;
|
|
case EP_PATCH:
|
|
case EP_TILE:
|
|
default:
|
|
return pselSet;
|
|
}
|
|
}
|
|
|
|
GenericNamedSelSetList &EditPatchData::GetSelSet(int level)
|
|
{
|
|
switch (level + EP_VERTEX)
|
|
{
|
|
case EP_VERTEX:
|
|
return vselSet;
|
|
case EP_EDGE:
|
|
return eselSet;
|
|
case EP_PATCH:
|
|
case EP_TILE:
|
|
default:
|
|
return pselSet;
|
|
}
|
|
}
|
|
|
|
|
|
void EditPatchData::UpdateChanges(PatchMesh *patch, RPatchMesh *rpatch, BOOL checkTopology)
|
|
{
|
|
if (theHold.Holding())
|
|
{
|
|
theHold.Put(new EPVertMapRestore(this));
|
|
//theHold.Put(new FinalPatchRestore(&finalPatch, &rfinalPatch));
|
|
if (rpatch)
|
|
theHold.Put(new FinalPatchRestore(&finalPatch, &rfinalPatch));
|
|
else
|
|
theHold.Put(new FinalPatchRestore(&finalPatch, NULL));
|
|
}
|
|
// Update the mapper's indices
|
|
if (checkTopology)
|
|
vertMap.UpdateMapping(*patch);
|
|
// Update mapper's XYZ deltas
|
|
vertMap.RecomputeDeltas(*patch);
|
|
// Store the final shape
|
|
finalPatch = *patch;
|
|
|
|
if (rpatch)
|
|
rfinalPatch = *rpatch;
|
|
}
|
|
|
|
#define EPD_GENERAL_CHUNK 0x1000 // Obsolete as of 11/12/98 (r3)
|
|
#define CHANGE_CHUNK 0x1010 // Obsolete as of 11/12/98 (r3)
|
|
#define EPD_R3_GENERAL_CHUNK 0x1015
|
|
#define MESH_ATTRIB_CHUNK 0x1020
|
|
#define DISP_PARTS_CHUNK 0x1030
|
|
#define VTESS_ATTRIB_CHUNK 0x1070
|
|
#define PTESS_ATTRIB_CHUNK 0x1080
|
|
#define DTESS_ATTRIB_CHUNK 0x1090
|
|
#define NORMAL_TESS_ATTRIB_CHUNK 0x1110
|
|
#define WELD_TESS_ATTRIB_CHUNK 0x1120
|
|
#define VERTMAP_CHUNK 0x1130
|
|
#define FINALPATCH_CHUNK 0x1140
|
|
#define RENDERSTEPS_CHUNK 0x1150
|
|
#define SHOWINTERIOR_CHUNK 0x1160
|
|
|
|
// Named sel set chunks
|
|
#define VSELSET_CHUNK 0x1040
|
|
#define ESELSET_CHUNK 0x1050
|
|
#define PSELSET_CHUNK 0x1060
|
|
|
|
#define RPO_MODE_TILE 0x4000
|
|
#define RFINALPATCH_CHUNK 0x4001
|
|
#define RPO_MODE_TILE_TRANSITION 0x4002
|
|
#define RPO_INCLUDE_MESHES 0x4003
|
|
|
|
IOResult EditPatchData::Save(ISave *isave)
|
|
{
|
|
ULONG nb;
|
|
isave->BeginChunk(EPD_R3_GENERAL_CHUNK);
|
|
isave->Write(&flags, sizeof(DWORD), &nb);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(MESH_ATTRIB_CHUNK);
|
|
isave->Write(&meshSteps, sizeof(int), &nb);
|
|
// Future use (Not used now)
|
|
BOOL fakeAdaptive = FALSE;
|
|
isave->Write(&fakeAdaptive, sizeof(BOOL), &nb);
|
|
// isave->Write(&meshAdaptive,sizeof(BOOL),&nb); // Future use (Not used now)
|
|
isave->EndChunk();
|
|
|
|
// 3-18-99 to suport render steps and removal of the mental tesselator
|
|
isave->BeginChunk(RENDERSTEPS_CHUNK);
|
|
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
|
{
|
|
meshStepsRender = 5;
|
|
nlassert(0);
|
|
}
|
|
isave->Write(&meshStepsRender, sizeof(int), &nb);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(SHOWINTERIOR_CHUNK);
|
|
isave->Write(&showInterior, sizeof(BOOL), &nb);
|
|
isave->EndChunk();
|
|
|
|
|
|
isave->BeginChunk(VTESS_ATTRIB_CHUNK);
|
|
viewTess.Save(isave);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(PTESS_ATTRIB_CHUNK);
|
|
prodTess.Save(isave);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(DTESS_ATTRIB_CHUNK);
|
|
dispTess.Save(isave);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(DISP_PARTS_CHUNK);
|
|
isave->Write(&displaySurface, sizeof(BOOL), &nb);
|
|
isave->Write(&displayLattice, sizeof(BOOL), &nb);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(NORMAL_TESS_ATTRIB_CHUNK);
|
|
isave->Write(&mViewTessNormals, sizeof(BOOL), &nb);
|
|
isave->Write(&mProdTessNormals, sizeof(BOOL), &nb);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(WELD_TESS_ATTRIB_CHUNK);
|
|
isave->Write(&mViewTessWeld, sizeof(BOOL), &nb);
|
|
isave->Write(&mProdTessWeld, sizeof(BOOL), &nb);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(RPO_MODE_TILE);
|
|
isave->Write(&tileMode, sizeof(tileMode), &nb);
|
|
isave->Write(&tileLevel, sizeof(tileLevel), &nb);
|
|
isave->Write(&keepMapping, sizeof(keepMapping), &nb);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(RPO_INCLUDE_MESHES);
|
|
isave->Write(&includeMeshes, sizeof(includeMeshes), &nb);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(RPO_MODE_TILE_TRANSITION);
|
|
isave->Write(&transitionType, sizeof(transitionType), &nb);
|
|
isave->EndChunk();
|
|
|
|
// Save named sel sets
|
|
if (vselSet.Count())
|
|
{
|
|
isave->BeginChunk(VSELSET_CHUNK);
|
|
vselSet.Save(isave);
|
|
isave->EndChunk();
|
|
}
|
|
if (eselSet.Count())
|
|
{
|
|
isave->BeginChunk(ESELSET_CHUNK);
|
|
eselSet.Save(isave);
|
|
isave->EndChunk();
|
|
}
|
|
if (pselSet.Count())
|
|
{
|
|
isave->BeginChunk(PSELSET_CHUNK);
|
|
pselSet.Save(isave);
|
|
isave->EndChunk();
|
|
}
|
|
|
|
isave->BeginChunk(VERTMAP_CHUNK);
|
|
vertMap.Save(isave);
|
|
isave->EndChunk();
|
|
isave->BeginChunk(FINALPATCH_CHUNK);
|
|
finalPatch.Save(isave);
|
|
isave->EndChunk();
|
|
|
|
isave->BeginChunk(RFINALPATCH_CHUNK);
|
|
rfinalPatch.Save(isave);
|
|
isave->EndChunk();
|
|
|
|
return IO_OK;
|
|
}
|
|
|
|
IOResult EditPatchData::Load(ILoad *iload)
|
|
{
|
|
IOResult res;
|
|
ULONG nb;
|
|
PModRecord *theChange;
|
|
while (IO_OK == (res = iload->OpenChunk()))
|
|
{
|
|
switch (iload->CurChunkID())
|
|
{
|
|
// The following code is here to load pre-release 3 files.
|
|
case EPD_GENERAL_CHUNK:
|
|
iload->SetObsolete();
|
|
iload->Read(&flags, sizeof(DWORD), &nb);
|
|
break;
|
|
case CLEARVERTSELRECORD_CHUNK:
|
|
theChange = new ClearPVertSelRecord;
|
|
goto load_change;
|
|
case SETVERTSELRECORD_CHUNK:
|
|
theChange = new SetPVertSelRecord;
|
|
goto load_change;
|
|
case INVERTVERTSELRECORD_CHUNK:
|
|
theChange = new InvertPVertSelRecord;
|
|
goto load_change;
|
|
case CLEAREDGESELRECORD_CHUNK:
|
|
theChange = new ClearPEdgeSelRecord;
|
|
goto load_change;
|
|
case SETEDGESELRECORD_CHUNK:
|
|
theChange = new SetPEdgeSelRecord;
|
|
goto load_change;
|
|
case INVERTEDGESELRECORD_CHUNK:
|
|
theChange = new InvertPEdgeSelRecord;
|
|
goto load_change;
|
|
case CLEARPATCHSELRECORD_CHUNK:
|
|
theChange = new ClearPatchSelRecord;
|
|
goto load_change;
|
|
case SETPATCHSELRECORD_CHUNK:
|
|
theChange = new SetPatchSelRecord;
|
|
goto load_change;
|
|
case INVERTPATCHSELRECORD_CHUNK:
|
|
theChange = new InvertPatchSelRecord;
|
|
goto load_change;
|
|
case VERTSELRECORD_CHUNK:
|
|
theChange = new PVertSelRecord;
|
|
goto load_change;
|
|
case EDGESELRECORD_CHUNK:
|
|
theChange = new PEdgeSelRecord;
|
|
goto load_change;
|
|
case PATCHSELRECORD_CHUNK:
|
|
theChange = new PatchSelRecord;
|
|
goto load_change;
|
|
case PATCHDELETERECORD_CHUNK:
|
|
theChange = new PatchDeleteRecord;
|
|
goto load_change;
|
|
case VERTMOVERECORD_CHUNK:
|
|
theChange = new PVertMoveRecord;
|
|
goto load_change;
|
|
case PATCHCHANGERECORD_CHUNK:
|
|
theChange = new PatchChangeRecord;
|
|
goto load_change;
|
|
case VERTCHANGERECORD_CHUNK:
|
|
theChange = new PVertChangeRecord;
|
|
goto load_change;
|
|
case PATCHADDRECORD_CHUNK:
|
|
theChange = new PatchAddRecord;
|
|
goto load_change;
|
|
case EDGESUBDIVIDERECORD_CHUNK:
|
|
theChange = new EdgeSubdivideRecord;
|
|
goto load_change;
|
|
case PATCHSUBDIVIDERECORD_CHUNK:
|
|
theChange = new PatchSubdivideRecord;
|
|
goto load_change;
|
|
case PATTACHRECORD_CHUNK:
|
|
theChange = new PAttachRecord;
|
|
goto load_change;
|
|
case PATCHDETACHRECORD_CHUNK:
|
|
theChange = new PatchDetachRecord;
|
|
goto load_change;
|
|
case PATCHMTLRECORD_CHUNK:
|
|
theChange = new PatchMtlRecord;
|
|
goto load_change;
|
|
case VERTWELDRECORD_CHUNK:
|
|
theChange = new PVertWeldRecord;
|
|
goto load_change;
|
|
case VERTDELETERECORD_CHUNK:
|
|
theChange = new PVertDeleteRecord;
|
|
// Intentional fall-thru!
|
|
load_change:
|
|
changes.Append(1, &theChange);
|
|
changes[changes.Count() - 1]->Load(iload);
|
|
break;
|
|
//
|
|
// The following code is used for post-release 3 files
|
|
//
|
|
case EPD_R3_GENERAL_CHUNK:
|
|
res = iload->Read(&flags, sizeof(DWORD), &nb);
|
|
break;
|
|
case VERTMAP_CHUNK:
|
|
res = vertMap.Load(iload);
|
|
break;
|
|
case FINALPATCH_CHUNK:
|
|
res = finalPatch.Load(iload);
|
|
break;
|
|
case RFINALPATCH_CHUNK:
|
|
res = rfinalPatch.Load(iload);
|
|
break;
|
|
//
|
|
// The following code is common to all versions' files
|
|
//
|
|
case MESH_ATTRIB_CHUNK:
|
|
iload->Read(&meshSteps, sizeof(int), &nb);
|
|
res = iload->Read(&meshAdaptive, sizeof(BOOL), &nb); // Future use (Not used now)
|
|
break;
|
|
// 3-18-99 to suport render steps and removal of the mental tesselator
|
|
case RENDERSTEPS_CHUNK:
|
|
iload->Read(&meshStepsRender, sizeof(int), &nb);
|
|
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
|
{
|
|
meshStepsRender = 5;
|
|
nlassert(0);
|
|
}
|
|
|
|
break;
|
|
case SHOWINTERIOR_CHUNK:
|
|
iload->Read(&showInterior, sizeof(BOOL), &nb);
|
|
break;
|
|
|
|
case VTESS_ATTRIB_CHUNK:
|
|
viewTess.Load(iload);
|
|
break;
|
|
case PTESS_ATTRIB_CHUNK:
|
|
prodTess.Load(iload);
|
|
break;
|
|
case DTESS_ATTRIB_CHUNK:
|
|
dispTess.Load(iload);
|
|
break;
|
|
case NORMAL_TESS_ATTRIB_CHUNK:
|
|
iload->Read(&mViewTessNormals, sizeof(BOOL), &nb);
|
|
res = iload->Read(&mProdTessNormals, sizeof(BOOL), &nb);
|
|
break;
|
|
case WELD_TESS_ATTRIB_CHUNK:
|
|
iload->Read(&mViewTessWeld, sizeof(BOOL), &nb);
|
|
res = iload->Read(&mProdTessWeld, sizeof(BOOL), &nb);
|
|
break;
|
|
case DISP_PARTS_CHUNK:
|
|
iload->Read(&displaySurface, sizeof(BOOL), &nb);
|
|
res = iload->Read(&displayLattice, sizeof(BOOL), &nb);
|
|
break;
|
|
// Load named selection sets
|
|
case VSELSET_CHUNK:
|
|
res = vselSet.Load(iload);
|
|
break;
|
|
case PSELSET_CHUNK:
|
|
res = pselSet.Load(iload);
|
|
break;
|
|
case ESELSET_CHUNK:
|
|
res = eselSet.Load(iload);
|
|
break;
|
|
|
|
case RPO_MODE_TILE:
|
|
res = iload->Read(&tileMode, sizeof(tileMode), &nb);
|
|
res = iload->Read(&tileLevel, sizeof(tileLevel), &nb);
|
|
res = iload->Read(&keepMapping, sizeof(keepMapping), &nb);
|
|
break;
|
|
|
|
case RPO_INCLUDE_MESHES:
|
|
res = iload->Read(&includeMeshes, sizeof(includeMeshes), &nb);
|
|
break;
|
|
|
|
case RPO_MODE_TILE_TRANSITION:
|
|
res = iload->Read(&transitionType, sizeof(transitionType), &nb);
|
|
break;
|
|
}
|
|
iload->CloseChunk();
|
|
if (res != IO_OK)
|
|
return res;
|
|
}
|
|
return IO_OK;
|
|
}
|