Skip to content

Commit 9a05150

Browse files
author
Pavel Kovalenko
committed
Fix LightWave and 3DS Max exporters compilation issues. Close #7.
1 parent 508f8e9 commit 9a05150

28 files changed

+679
-368
lines changed

src/editors/ECore/Editor/EditObject.h

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ class ECORE_API CSurface
6060
shared_str m_GameMtlName;
6161
Flags32 m_Flags;
6262
u32 m_dwFVF;
63-
63+
#ifdef _MAX_EXPORT
64+
u32 mid;
65+
Mtl* mtl;
66+
#endif
6467
Flags32 m_RTFlags;
6568
u32 tag;
6669
SSimpleImage* m_ImageData;
@@ -73,6 +76,10 @@ class ECORE_API CSurface
7376
m_RTFlags.zero ();
7477
m_Flags.zero ();
7578
m_dwFVF = 0;
79+
#ifdef _MAX_EXPORT
80+
mtl = 0;
81+
mid = 0;
82+
#endif
7683
tag = 0;
7784
}
7885
IC bool Validate ()
@@ -367,9 +374,13 @@ public CPhysicsShellHolderEditorBase
367374

368375
// load/save methods
369376
bool Reload ();
370-
bool Load (LPCSTR fname);
371-
bool Save (LPCSTR fname);
372-
bool Load (IReader&);
377+
#ifdef _EDITOR
378+
bool Load (LPCSTR fname);
379+
#endif
380+
#if defined(_EDITOR) || defined(_MAYA_EXPORT)
381+
bool Load (IReader&);
382+
#endif
383+
bool Save (LPCSTR fname);
373384
void Save (IWriter&);
374385
#ifdef _EDITOR
375386
void FillMotionList (LPCSTR pref, ListItemsVec& items, int modeID);
@@ -380,7 +391,7 @@ public CPhysicsShellHolderEditorBase
380391
void FillSummaryProps (LPCSTR pref, PropItemVec& items);
381392
bool CheckShaderCompatible ();
382393
#endif
383-
394+
384395
// contains methods
385396
CEditableMesh* FindMeshByName (LPCSTR name, CEditableMesh* Ignore=0);
386397
void VerifyMeshNames ();
@@ -408,6 +419,7 @@ public CPhysicsShellHolderEditorBase
408419
bool PrepareSkeletonOGF (IWriter& F, u8 infl);
409420
// rigid
410421
bool PrepareRigidOGF (IWriter& F, bool gen_tb, CEditableMesh* mesh);
422+
#if defined(_EDITOR) || defined(_MAYA_EXPORT)
411423
// ogf
412424
bool PrepareOGF (IWriter& F, u8 infl, bool gen_tb, CEditableMesh* mesh);
413425
bool ExportOGF (LPCSTR fname, u8 skl_infl);
@@ -416,8 +428,21 @@ public CPhysicsShellHolderEditorBase
416428
bool ExportOMF (LPCSTR fname);
417429
// obj
418430
bool ExportOBJ (LPCSTR name);
419-
431+
#endif
420432
LPCSTR GenerateSurfaceName (LPCSTR base_name);
433+
#ifdef _MAX_EXPORT
434+
BOOL ExtractTexName (Texmap *src, LPSTR dest);
435+
BOOL ParseStdMaterial (StdMat* src, CSurface* dest);
436+
BOOL ParseMultiMaterial (MultiMtl* src, u32 mid, CSurface* dest);
437+
BOOL ParseXRayMaterial (XRayMtl* src, u32 mid, CSurface* dest);
438+
CSurface* CreateSurface (Mtl* M, u32 mat_id);
439+
bool ImportMAXSkeleton (CExporter* exporter);
440+
#endif
441+
#ifdef _LW_EXPORT
442+
bool ImportLWO(const char* fname, bool optimize);
443+
bool ImportLWO (st_ObjectDB *I);
444+
Flags32 m_Flags;
445+
#endif
421446
#ifdef _MAYA_EXPORT
422447
BOOL ParseMAMaterial (CSurface* dest, SXRShaderData& d);
423448
CSurface* CreateSurface (LPCSTR m_name, SXRShaderData& d);

src/editors/ECore/Editor/EditObjectIO.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void CEditableObject::Save(IWriter& F)
199199
bOnModified = false;
200200
}
201201

202-
#if 1 //#ifdef _EDITOR
202+
#if defined(_EDITOR) || defined(_MAYA_EXPORT)
203203

204204
bool CEditableObject::Load(IReader& F)
205205
{

src/editors/ECore/Editor/EditObjectImport.cpp

Lines changed: 292 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,297 @@ extern "C" {
1717
#ifdef _EDITOR
1818
#include "ResourceManager.h"
1919

20-
extern "C" __declspec(dllimport) lwObject* LWO_ImportObject(char* filename, lwObject *new_obj);
21-
extern "C" __declspec(dllimport) void LWO_CloseFile(lwObject *new_obj);
20+
extern "C" __declspec(dllimport) lwObject* LWOImportObject(char* filename);
21+
extern "C" __declspec(dllimport) void LWOCloseFile(lwObject* object);
2222
#endif
2323

24-
DEFINE_MAP(void*,int,VMIndexLink,VMIndexLinkIt);
25-
26-
bool CompareFunc(const st_VMapPt& vm0, const st_VMapPt& vm1){
27-
return vm0.vmap_index<vm1.vmap_index;
28-
};
29-
30-
24+
#ifdef _LW_EXPORT
25+
bool CEditableObject::ImportLWO(const char* fn, bool optimize)
26+
{
27+
string512 fname;
28+
strcpy(fname, fn);
29+
#ifdef _EDITOR
30+
lwObject* lwObj = LWOImportObject(fname);
31+
#else
32+
u32 errId;
33+
int errPos;
34+
lwObject* lwObj = lwGetObject(fname, &errId, &errPos);
35+
#endif
36+
if (!lwObj)
37+
{
38+
ELog.DlgMsg(mtError, "Can't import LWO object file!");
39+
return false;
40+
}
41+
ELog.Msg(mtInformation, "CEditableObject: import lwo %s...", fname);
42+
bool result = false; // assume fail
43+
// parse lwo object
44+
m_Meshes.reserve(lwObj->nlayers);
45+
m_Surfaces.reserve(lwObj->nsurfs);
46+
int surfaceId = 0;
47+
for (lwSurface* lwSurf = lwObj->surf; lwSurf; lwSurf = lwSurf->next)
48+
{
49+
lwSurf->alpha_mode = surfaceId; // save surface id for internal use
50+
auto surf = new CSurface();
51+
m_Surfaces.push_back(surf);
52+
surf->SetName(lwSurf->name && lwSurf->name[0] ? lwSurf->name : "Default");
53+
surf->m_Flags.set(CSurface::sf2Sided, lwSurf->sideflags == 3);
54+
AnsiString enName = "default", lcName = "default", gmName = "default";
55+
if (lwSurf->nshaders && !stricmp(lwSurf->shader->name, SH_PLUGIN_NAME))
56+
{
57+
auto shader = (XRShader*)lwSurf->shader->data;
58+
enName = shader->en_name;
59+
lcName = shader->lc_name;
60+
gmName = shader->gm_name;
61+
}
62+
else
63+
ELog.Msg(mtError, "CEditableObject: Shader not found on surface '%s'.", surf->_Name());
64+
#ifdef _EDITOR
65+
if (!Device.Resources->_FindBlender(enName.c_str()))
66+
{
67+
ELog.Msg(mtError, "CEditableObject: Render shader '%s' - can't find in library.\n"
68+
"Using 'default' shader on surface '%s'.", enName.c_str(), surf->_Name());
69+
enName = "default";
70+
}
71+
if (!Device.ShaderXRLC.Get(lcName.c_str()))
72+
{
73+
ELog.Msg(mtError, "CEditableObject: Compiler shader '%s' - can't find in library.\n"
74+
"Using 'default' shader on surface '%s'.", lcName.c_str(), surf->_Name());
75+
lcName = "default";
76+
}
77+
if (!GMLib.GetMaterial(gmName.c_str()))
78+
{
79+
ELog.Msg(mtError, "CEditableObject: Game material '%s' - can't find in library.\n"
80+
"Using 'default' material on surface '%s'.", lcName.c_str(), surf->_Name());
81+
gmName = "default";
82+
}
83+
#endif
84+
// fill texture layers
85+
u32 textureCount = 0;
86+
for (st_lwTexture* Itx = lwSurf->color.tex; Itx; Itx = Itx->next)
87+
{
88+
string1024 tname = "";
89+
textureCount++;
90+
int cidx = -1;
91+
if (Itx->type == ID_IMAP)
92+
cidx = Itx->param.imap.cindex;
93+
else
94+
{
95+
ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): 'Texture' is not Image Map!", surf->_Name());
96+
goto importFailed;
97+
}
98+
if (cidx != -1)
99+
{
100+
// get textures
101+
for (st_lwClip* lwClip = lwObj->clip; lwClip; lwClip = lwClip->next)
102+
{
103+
if (cidx == lwClip->index && lwClip->type == ID_STIL)
104+
{
105+
strcpy(tname, lwClip->source.still.name);
106+
break;
107+
}
108+
}
109+
if (tname[0] == 0)
110+
{
111+
ELog.DlgMsg(mtError, "Import LWO (Surface '%s'): "
112+
"'Texture' name is empty or non 'STIL' type!", surf->_Name());
113+
goto importFailed;
114+
}
115+
string256 textureName;
116+
_splitpath(tname, nullptr, nullptr, textureName, nullptr);
117+
surf->SetTexture(EFS.AppendFolderToName(textureName, 256, 1, true));
118+
// get vmap refs
119+
surf->SetVMap(Itx->param.imap.vmap_name);
120+
}
121+
}
122+
if (!surf->_VMap() || *surf->_VMap() == 0)
123+
{
124+
ELog.DlgMsg(mtError, "Invalid surface '%s'. Empty VMap.", surf->_Name());
125+
goto importFailed;
126+
}
127+
if (!surf->_Texture() || *surf->_Texture() == 0)
128+
{
129+
ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Textures empty.", surf->_Name());
130+
goto importFailed;
131+
}
132+
if (enName.c_str() == 0)
133+
{
134+
ELog.DlgMsg(mtError, "Can't create shader. Invalid surface '%s'. Shader empty.", surf->_Name());
135+
goto importFailed;
136+
}
137+
surf->SetShader(enName.c_str());
138+
surf->SetShaderXRLC(lcName.c_str());
139+
surf->SetGameMtl(gmName.c_str());
140+
surf->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | textureCount << D3DFVF_TEXCOUNT_SHIFT);
141+
surfaceId++;
142+
}
143+
// process mesh layers
144+
for (st_lwLayer* lwLayer = lwObj->layer; lwLayer; lwLayer = lwLayer->next)
145+
{
146+
auto mesh = new CEditableMesh(this);
147+
m_Meshes.push_back(mesh);
148+
mesh->SetName(lwLayer->name ? lwLayer->name : "");
149+
auto bbox = lwLayer->bbox;
150+
mesh->m_Box.set(bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5]);
151+
// parse mesh(lwo-layer) data
152+
if (lwLayer->nvmaps == 0)
153+
{
154+
ELog.DlgMsg(mtError, "Import LWO: Mesh layer must contain UV map!");
155+
goto importFailed;
156+
}
157+
// XXX nitrocaster: incompatible with multithreaded import
158+
static xr_map<void*, int> vmIndices;
159+
vmIndices.clear();
160+
int vmIndex = 0;
161+
for (st_lwVMap* lwVmap = lwLayer->vmap; lwVmap; lwVmap = lwVmap->next)
162+
{
163+
switch (lwVmap->type)
164+
{
165+
case ID_TXUV:
166+
{
167+
if (lwVmap->dim != 2)
168+
{
169+
ELog.DlgMsg(mtError, "Import LWO: 'UV Map' must be equal to 2!");
170+
goto importFailed;
171+
}
172+
mesh->m_VMaps.push_back(new st_VMap(lwVmap->name, vmtUV, !!lwVmap->perpoly));
173+
st_VMap* vmap = mesh->m_VMaps.back();
174+
vmap->copyfrom(*lwVmap->val, lwVmap->nverts);
175+
// flip uv
176+
for (int uvIndex = 0; uvIndex < vmap->size(); uvIndex++)
177+
{
178+
Fvector2& uv = vmap->getUV(uvIndex);
179+
uv.y = 1.f - uv.y;
180+
}
181+
vmIndices[lwVmap] = vmIndex++;
182+
break;
183+
}
184+
case ID_WGHT:
185+
{
186+
if (lwVmap->dim != 1)
187+
{
188+
ELog.DlgMsg(mtError, "Import LWO: 'Weight' must be equal to 1!");
189+
goto importFailed;
190+
}
191+
mesh->m_VMaps.push_back(new st_VMap(lwVmap->name, vmtWeight, false));
192+
st_VMap* vmap = mesh->m_VMaps.back();
193+
vmap->copyfrom(*lwVmap->val, lwVmap->nverts);
194+
vmIndices[lwVmap] = vmIndex++;
195+
break;
196+
}
197+
case ID_PICK: ELog.Msg(mtError, "Found 'PICK' VMAP. Import failed."); goto importFailed;
198+
case ID_MNVW: ELog.Msg(mtError, "Found 'MNVW' VMAP. Import failed."); goto importFailed;
199+
case ID_MORF: ELog.Msg(mtError, "Found 'MORF' VMAP. Import failed."); goto importFailed;
200+
case ID_SPOT: ELog.Msg(mtError, "Found 'SPOT' VMAP. Import failed."); goto importFailed;
201+
case ID_RGB: ELog.Msg(mtError, "Found 'RGB' VMAP. Import failed."); goto importFailed;
202+
case ID_RGBA: ELog.Msg(mtError, "Found 'RGBA' VMAP. Import failed."); goto importFailed;
203+
}
204+
}
205+
// points
206+
mesh->m_VertCount = lwLayer->point.count;
207+
mesh->m_Vertices = xr_alloc<Fvector>(mesh->m_VertCount);
208+
for (int i = 0; i < lwLayer->point.count; i++)
209+
{
210+
st_lwPoint& lwPoint = lwLayer->point.pt[i];
211+
Fvector& vertex = mesh->m_Vertices[i];
212+
vertex.set(lwPoint.pos);
213+
}
214+
// polygons
215+
mesh->m_FaceCount = lwLayer->polygon.count;
216+
mesh->m_Faces = xr_alloc<st_Face>(mesh->m_FaceCount);
217+
mesh->m_SmoothGroups = xr_alloc<u32>(mesh->m_FaceCount);
218+
memset(mesh->m_SmoothGroups, u32(-1), mesh->m_FaceCount);
219+
mesh->m_VMRefs.reserve(lwLayer->polygon.count*3);
220+
xr_vector<int> surfIds(lwLayer->polygon.count);
221+
for (int i = 0; i < lwLayer->polygon.count; i++)
222+
{
223+
st_Face& face = mesh->m_Faces[i];
224+
st_lwPolygon& lwPoly = lwLayer->polygon.pol[i];
225+
if (lwPoly.nverts != 3)
226+
{
227+
ELog.DlgMsg(mtError, "Import LWO: Face must contain only 3 vertices!");
228+
goto importFailed;
229+
}
230+
for (int fvIndex = 0; fvIndex < 3; fvIndex++)
231+
{
232+
st_lwPolVert& lwFaceVert = lwPoly.v[fvIndex];
233+
st_FaceVert& faceVert = face.pv[fvIndex];
234+
faceVert.pindex = lwFaceVert.index;
235+
mesh->m_VMRefs.push_back(st_VMapPtLst());
236+
st_VMapPtLst& vmPointList = mesh->m_VMRefs.back();
237+
faceVert.vmref = mesh->m_VMRefs.size()-1;
238+
// parse uv-map
239+
st_lwPoint& lwPoint = lwLayer->point.pt[faceVert.pindex];
240+
if (lwFaceVert.nvmaps == 0 && lwPoint.nvmaps == 0)
241+
{
242+
ELog.DlgMsg(mtError, "Found mesh without UV's!");
243+
goto importFailed;
244+
}
245+
xr_vector<st_VMapPt> vmPoints;
246+
AStringVec names;
247+
// process polys
248+
for (int j = 0; j < lwFaceVert.nvmaps; j++)
249+
{
250+
if (lwFaceVert.vm[j].vmap->type != ID_TXUV)
251+
continue;
252+
vmPoints.push_back(st_VMapPt());
253+
st_VMapPt& pt = vmPoints.back();
254+
pt.vmap_index = vmIndices[lwFaceVert.vm[j].vmap]; // VMap id
255+
names.push_back(lwFaceVert.vm[j].vmap->name);
256+
pt.index = lwFaceVert.vm[j].index;
257+
}
258+
// process points
259+
for (int j = 0; j < lwPoint.nvmaps; j++)
260+
{
261+
if (lwPoint.vm[j].vmap->type != ID_TXUV)
262+
continue;
263+
if (std::find(names.begin(), names.end(), lwPoint.vm[j].vmap->name) != names.end())
264+
continue;
265+
vmPoints.push_back(st_VMapPt());
266+
st_VMapPt& pt = vmPoints.back();
267+
pt.vmap_index = vmIndices[lwPoint.vm[j].vmap]; // VMap id
268+
pt.index = lwPoint.vm[j].index;
269+
}
270+
auto cmpFunc = [](const st_VMapPt& a, const st_VMapPt& b)
271+
{ return a.vmap_index < b.vmap_index; };
272+
std::sort(vmPoints.begin(), vmPoints.end(), cmpFunc);
273+
// parse weight-map
274+
for (int j = 0; j < lwPoint.nvmaps; j++)
275+
{
276+
if (lwPoint.vm[j].vmap->type != ID_WGHT)
277+
continue;
278+
vmPoints.push_back(st_VMapPt());
279+
st_VMapPt& pt = vmPoints.back();
280+
pt.vmap_index = vmIndices[lwPoint.vm[j].vmap]; // VMap id
281+
pt.index = lwPoint.vm[j].index;
282+
}
283+
vmPointList.count = vmPoints.size();
284+
vmPointList.pts = xr_alloc<st_VMapPt>(vmPointList.count);
285+
memcpy(vmPointList.pts, &*vmPoints.begin(), vmPointList.count*sizeof(st_VMapPt));
286+
}
287+
// lwPoly.surf->alpha_mode stores reviously saved surface id
288+
surfIds[i] = lwPoly.surf->alpha_mode;
289+
}
290+
for (u32 polyId = 0; polyId < mesh->GetFCount(); polyId++)
291+
mesh->m_SurfFaces[m_Surfaces[surfIds[polyId]]].push_back(polyId);
292+
if (optimize)
293+
mesh->OptimizeMesh(false);
294+
mesh->RebuildVMaps();
295+
}
296+
result = true;
297+
importFailed:
298+
#ifdef _EDITOR
299+
LWOCloseFile(lwObj);
300+
#else
301+
lwFreeObject(lwObj);
302+
#endif
303+
if (result)
304+
{
305+
VerifyMeshNames();
306+
char* ext = strext(fname);
307+
m_LoadName = ext ? strcpy(ext, ".object") : strcat(fname, ".object");
308+
}
309+
else
310+
ELog.DlgMsg(mtError, "Can't parse LWO object.");
311+
return result;
312+
}
313+
#endif

0 commit comments

Comments
 (0)