khanat-opennel-code/code/nel/tools/3d/plugin_max/nel_patch_edit_adv/NP_EPVertMapper.cpp
2010-05-06 02:08:41 +02:00

301 lines
7.6 KiB
C++

#include "stdafx.h"
#include "editpat.h"
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#define DBGWELD_DUMPx
#define DBGWELD_ACTIONx
#define DBG_NAMEDSELSx
// ------------------------------------------------------------------------------------------------------------------------------------------------------
extern Point3 zeroPoint;
// ------------------------------------------------------------------------------------------------------------------------------------------------------
EPVertMapper::~EPVertMapper()
{
if (vertMap)
{
delete[] vertMap;
vertMap = NULL;
}
if (vecMap)
{
delete[] vecMap;
vecMap = NULL;
}
}
void EPVertMapper::Build(PatchMesh &patch)
{
verts = patch.numVerts;
if (vertMap)
delete[] vertMap;
vertMap = new EPMapVert[verts];
vecs = patch.numVecs;
if (vecMap)
delete[] vecMap;
vecMap = new EPMapVert[vecs];
int i;
for (i = 0; i < verts; ++i)
vertMap[i] = EPMapVert(i, patch.verts[i].p, zeroPoint);
for (i = 0; i < vecs; ++i)
vecMap[i] = EPMapVert(i, patch.vecs[i].p, zeroPoint);
}
void EPVertMapper::RecordTopologyTags(PatchMesh &patch)
{
int i;
for (i = 0; i < verts; ++i)
{
// If it's still mapped, record it!
if (vertMap[i].vert >= 0)
patch.verts[vertMap[i].vert].aux1 = i;
}
for (i = 0; i < vecs; ++i)
{
// If it's still mapped, record it!
if (vecMap[i].vert >= 0)
patch.vecs[vecMap[i].vert].aux1 = i;
}
}
void EPVertMapper::UpdateMapping(PatchMesh &patch)
{
// Flush existing mapping
int i;
for (i = 0; i < verts; ++i)
vertMap[i].vert = -1;
for (i = 0; i < vecs; ++i)
vecMap[i].vert = -1;
// Build the new mapping
int verts = patch.numVerts;
for (int vert = 0; vert < verts; ++vert)
{
int aux = patch.verts[vert].aux1;
if (aux != 0xffffffff)
vertMap[aux].vert = vert;
}
int vecs = patch.numVecs;
for (int vec = 0; vec < vecs; ++vec)
{
int aux = patch.vecs[vec].aux1;
if (aux != 0xffffffff)
vecMap[aux].vert = vec;
}
}
void EPVertMapper::RecomputeDeltas(PatchMesh &patch)
{
int i;
for (i = 0; i < verts; ++i)
{
EPMapVert &map = vertMap[i];
if (map.vert >= 0 && map.originalStored)
{
Point3 pnew = patch.verts[map.vert].p;
#ifdef VMAP_DEBUG
Point3 oldDelta = map.delta;
#endif
map.delta = pnew - map.original;
#ifdef VMAP_DEBUG
if (map.delta != oldDelta)
DebugPrint("Vert %d delta changed from %.2f %.2f %.2f to %.2 %.2f %.2f\n", i, oldDelta.x, oldDelta.y, oldDelta.z, map.delta.x, map.delta.y, map.delta.z);
#endif
}
}
for (i = 0; i < vecs; ++i)
{
EPMapVert &map = vecMap[i];
if (map.vert >= 0 && map.originalStored)
{
Point3 pnew = patch.vecs[map.vert].p;
#ifdef VMAP_DEBUG
Point3 oldDelta = map.delta;
#endif
map.delta = pnew - map.original;
#ifdef VMAP_DEBUG
if (map.delta != oldDelta)
DebugPrint("Vec %d delta changed from %.2f %.2f %.2f to %.2 %.2f %.2f\n", i, oldDelta.x, oldDelta.y, oldDelta.z, map.delta.x, map.delta.y, map.delta.z);
#endif
}
}
}
void EPVertMapper::UpdateAndApplyDeltas(PatchMesh &inPatch, PatchMesh &outPatch)
{
// watje 4-27-99 here to handle 0 patch situations
if (inPatch.numPatches == 0)
{
// outPatch.setNumVerts(0,TRUE);
return;
}
// Update the original point locations
int i;
for (i = 0; i < verts; ++i)
{
// If this table has more in it than we need, forget the rest
// This can happen if the input object changes to fewer verts
if (i >= inPatch.numVerts)
break;
// If it's still mapped, update it!
if (vertMap[i].vert >= 0)
{
vertMap[i].original = inPatch.verts[i].p;
vertMap[i].originalStored = TRUE;
}
}
for (i = 0; i < vecs; ++i)
{
// If this table has more in it than we need, forget the rest
// This can happen if the input object changes to fewer vecs
if (i >= inPatch.numVecs)
break;
// If it's still mapped, update it!
if (vecMap[i].vert >= 0)
{
vecMap[i].original = inPatch.vecs[i].p;
vecMap[i].originalStored = TRUE;
}
}
// Now apply to output
for (i = 0; i < verts; ++i)
{
EPMapVert &pv = vertMap[i];
if (pv.vert >= 0 && pv.originalStored)
{
// nlassert(pv.vert >= 0 && pv.vert < outPatch.numVerts);
// watje 4-27-99 instead just throwing an nlassert it pops a message box up and troes to recover
if (!(pv.vert >= 0 && pv.vert < outPatch.numVerts))
{
outPatch.setNumVerts(pv.vert + 1, TRUE);
TSTR title = GetString(IDS_TH_EDITPATCH_CLASS),
warning = GetString(IDS_PW_SURFACEERROR);
MessageBox(GetCOREInterface()->GetMAXHWnd(),
warning, title, MB_OK | MB_APPLMODAL);
}
if (i >= inPatch.numVerts)
outPatch.verts[pv.vert].p = zeroPoint;
else
outPatch.verts[pv.vert].p = pv.original + pv.delta;
#ifdef VMAP_DEBUG
if (pv.delta != zeroPoint)
DebugPrint("Vert %d applied delta of %.2f %.2f %.2f\n", i, pv.delta.x, pv.delta.y, pv.delta.z);
#endif
}
}
for (i = 0; i < vecs; ++i)
{
EPMapVert &pv = vecMap[i];
if (pv.vert >= 0 && pv.originalStored)
{
// nlassert(pv.vert >= 0 && pv.vert < outPatch.numVecs);
// watje 4-27-99 instead just throwing an nlassert it pops a message box up and troes to recover
if (!(pv.vert >= 0 && pv.vert < outPatch.numVecs))
{
outPatch.setNumVecs(pv.vert + 1, TRUE);
TSTR title = GetString(IDS_TH_EDITPATCH_CLASS),
warning = GetString(IDS_PW_SURFACEERROR);
MessageBox(GetCOREInterface()->GetMAXHWnd(),
warning, title, MB_OK | MB_APPLMODAL);
}
if (i >= inPatch.numVecs)
outPatch.vecs[pv.vert].p = zeroPoint;
else
outPatch.vecs[pv.vert].p = pv.original + pv.delta;
#ifdef VMAP_DEBUG
if (pv.delta != zeroPoint)
DebugPrint("Vec %d applied delta of %.2f %.2f %.2f\n", i, pv.delta.x, pv.delta.y, pv.delta.z);
#endif
}
}
}
EPVertMapper& EPVertMapper::operator=(EPVertMapper &from)
{
if (vertMap)
delete[] vertMap;
verts = from.verts;
vertMap = new EPMapVert[verts];
int i;
for (i = 0; i < verts; ++i)
vertMap[i] = from.vertMap[i];
if (vecMap)
delete[] vecMap;
vecs = from.vecs;
vecMap = new EPMapVert[vecs];
for (i = 0; i < vecs; ++i)
vecMap[i] = from.vecMap[i];
return *this;
}
void EPVertMapper::RescaleWorldUnits(float f)
{
int i;
for (i = 0; i < verts; ++i)
{
vertMap[i].delta *= f;
if (vertMap[i].originalStored)
vertMap[i].original *= f;
}
for (i = 0; i < vecs; ++i)
{
vecMap[i].delta *= f;
if (vecMap[i].originalStored)
vecMap[i].original *= f;
}
}
#define EPVM_DATA_CHUNK 0x1000
IOResult EPVertMapper::Save(ISave *isave)
{
ULONG nb;
isave->BeginChunk(EPVM_DATA_CHUNK);
isave->Write(&verts, sizeof(int), &nb);
isave->Write(vertMap, sizeof(EPMapVert) * verts, &nb);
isave->Write(&vecs, sizeof(int), &nb);
isave->Write(vecMap, sizeof(EPMapVert) * vecs, &nb);
isave->EndChunk();
return IO_OK;
}
IOResult EPVertMapper::Load(ILoad *iload)
{
IOResult res;
ULONG nb;
int index = 0;
while (IO_OK == (res = iload->OpenChunk()))
{
switch (iload->CurChunkID())
{
case EPVM_DATA_CHUNK:
res = iload->Read(&verts, sizeof(int), &nb);
if (vertMap)
delete[] vertMap;
vertMap = new EPMapVert[verts];
res = iload->Read(vertMap, sizeof(EPMapVert) * verts, &nb);
res = iload->Read(&vecs, sizeof(int), &nb);
if (vecMap)
delete[] vecMap;
vecMap = new EPMapVert[vecs];
res = iload->Read(vecMap, sizeof(EPMapVert) * vecs, &nb);
break;
}
iload->CloseChunk();
if (res != IO_OK)
return res;
}
return IO_OK;
}