2018-06-03 07:26:42 +00:00
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Copyright(C) 2018 Kevin Caccamo
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "r_data/models/models_obj.h"
|
|
|
|
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
/**
|
|
|
|
* Load an OBJ model
|
|
|
|
*
|
|
|
|
* @param fn The path to the model file
|
|
|
|
* @param lumpnum The lump index in the wad collection
|
|
|
|
* @param buffer The contents of the model file
|
|
|
|
* @param length The size of the model file
|
2018-06-06 05:08:05 +00:00
|
|
|
* @return Whether or not the model was parsed successfully
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length)
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
FString objName = Wads.GetLumpFullPath(lumpnum);
|
|
|
|
FString objBuf(buffer, length);
|
|
|
|
|
|
|
|
// Do some replacements before we parse the OBJ string
|
|
|
|
{
|
|
|
|
// Ensure usemtl statements remain intact
|
|
|
|
TArray<FString> mtlUsages;
|
|
|
|
TArray<long> mtlUsageIdxs;
|
|
|
|
long bpos = 0, nlpos = 0, slashpos = 0;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
bpos = objBuf.IndexOf("\nusemtl", bpos);
|
|
|
|
if (bpos == -1) break;
|
|
|
|
slashpos = objBuf.IndexOf('/', bpos);
|
|
|
|
nlpos = objBuf.IndexOf('\n', ++bpos);
|
|
|
|
if (slashpos > nlpos || slashpos == -1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (nlpos == -1)
|
|
|
|
{
|
2018-09-15 10:27:14 +00:00
|
|
|
nlpos = (long)objBuf.Len();
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
FString lineStr(objBuf.GetChars() + bpos, nlpos - bpos);
|
|
|
|
mtlUsages.Push(lineStr);
|
|
|
|
mtlUsageIdxs.Push(bpos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace forward slashes with percent signs so they aren't parsed as line comments
|
|
|
|
objBuf.ReplaceChars('/', *newSideSep);
|
2018-06-06 05:08:05 +00:00
|
|
|
char* wObjBuf = objBuf.LockBuffer();
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
|
|
|
// Substitute broken usemtl statements with old ones
|
|
|
|
for (size_t i = 0; i < mtlUsages.Size(); i++)
|
|
|
|
{
|
|
|
|
bpos = mtlUsageIdxs[i];
|
|
|
|
nlpos = objBuf.IndexOf('\n', bpos);
|
|
|
|
if (nlpos == -1)
|
|
|
|
{
|
2018-09-15 10:27:14 +00:00
|
|
|
nlpos = (long)objBuf.Len();
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-06-06 05:08:05 +00:00
|
|
|
memcpy(wObjBuf + bpos, mtlUsages[i].GetChars(), nlpos - bpos);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
bpos = 0;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
// Find each OBJ line comment, and convert each to a C-style line comment
|
|
|
|
while (1)
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
bpos = objBuf.IndexOf('#', bpos);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
if (bpos == -1) break;
|
2018-06-06 05:08:05 +00:00
|
|
|
if (objBuf[(unsigned int)bpos + 1] == '\n')
|
|
|
|
{
|
|
|
|
wObjBuf[bpos] = ' ';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wObjBuf[bpos] = '/';
|
|
|
|
wObjBuf[bpos+1] = '/';
|
|
|
|
}
|
|
|
|
bpos += 1;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-06-06 05:08:05 +00:00
|
|
|
wObjBuf = nullptr;
|
|
|
|
objBuf.UnlockBuffer();
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
sc.OpenString(objName, objBuf);
|
|
|
|
|
|
|
|
FTextureID curMtl = FNullTextureID();
|
|
|
|
OBJSurface *curSurface = nullptr;
|
2018-09-22 14:24:01 +00:00
|
|
|
unsigned int aggSurfFaceCount = 0;
|
|
|
|
unsigned int curSurfFaceCount = 0;
|
|
|
|
unsigned int curSmoothGroup = 0;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
|
|
|
while(sc.GetString())
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
if (sc.Compare("v")) // Vertex
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
ParseVector<FVector3, 3>(this->verts);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else if (sc.Compare("vn")) // Vertex normal
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
ParseVector<FVector3, 3>(this->norms);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else if (sc.Compare("vt")) // UV Coordinates
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
ParseVector<FVector2, 2>(this->uvs);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else if (sc.Compare("usemtl"))
|
|
|
|
{
|
|
|
|
// Get material name and try to load it
|
|
|
|
sc.MustGetString();
|
|
|
|
|
|
|
|
curMtl = LoadSkin("", sc.String);
|
|
|
|
if (!curMtl.isValid())
|
|
|
|
{
|
|
|
|
// Relative to model file path?
|
|
|
|
curMtl = LoadSkin(fn, sc.String);
|
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
if (!curMtl.isValid())
|
|
|
|
{
|
|
|
|
sc.ScriptMessage("Material %s (#%u) not found.", sc.String, surfaces.Size());
|
|
|
|
}
|
|
|
|
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
// Build surface...
|
|
|
|
if (curSurface == nullptr)
|
|
|
|
{
|
|
|
|
// First surface
|
|
|
|
curSurface = new OBJSurface(curMtl);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (curSurfFaceCount > 0)
|
|
|
|
{
|
|
|
|
// Add previous surface
|
|
|
|
curSurface->numFaces = curSurfFaceCount;
|
|
|
|
curSurface->faceStart = aggSurfFaceCount;
|
|
|
|
surfaces.Push(*curSurface);
|
|
|
|
delete curSurface;
|
|
|
|
// Go to next surface
|
|
|
|
curSurface = new OBJSurface(curMtl);
|
|
|
|
aggSurfFaceCount += curSurfFaceCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
curSurface->skin = curMtl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
curSurfFaceCount = 0;
|
|
|
|
}
|
|
|
|
else if (sc.Compare("f"))
|
|
|
|
{
|
|
|
|
FString sides[4];
|
|
|
|
OBJFace face;
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
// A face must have at least 3 sides
|
|
|
|
sc.MustGetString();
|
|
|
|
sides[i] = sc.String;
|
2018-06-06 05:08:05 +00:00
|
|
|
if (!ParseFaceSide(sides[i], face, i)) return false;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
face.sideCount = 3;
|
|
|
|
if (sc.GetString())
|
|
|
|
{
|
|
|
|
if (!sc.Compare("f") && FString(sc.String).IndexOfAny("-0123456789") == 0)
|
|
|
|
{
|
|
|
|
sides[3] = sc.String;
|
|
|
|
face.sideCount += 1;
|
2018-06-06 05:08:05 +00:00
|
|
|
if (!ParseFaceSide(sides[3], face, 3)) return false;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sc.UnGet(); // No 4th side, move back
|
|
|
|
}
|
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
face.smoothGroup = curSmoothGroup;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
faces.Push(face);
|
|
|
|
curSurfFaceCount += 1;
|
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
else if (sc.Compare("s"))
|
|
|
|
{
|
|
|
|
sc.MustGetString();
|
|
|
|
if (sc.Compare("off"))
|
|
|
|
{
|
|
|
|
curSmoothGroup = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sc.UnGet();
|
|
|
|
sc.MustGetNumber();
|
|
|
|
curSmoothGroup = sc.Number;
|
|
|
|
hasSmoothGroups = hasSmoothGroups || curSmoothGroup > 0;
|
|
|
|
}
|
|
|
|
}
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
sc.Close();
|
|
|
|
|
|
|
|
if (curSurface == nullptr)
|
|
|
|
{ // No valid materials detected
|
|
|
|
FTextureID dummyMtl = LoadSkin("", "-NOFLAT-"); // Built-in to GZDoom
|
|
|
|
curSurface = new OBJSurface(dummyMtl);
|
|
|
|
}
|
|
|
|
curSurface->numFaces = curSurfFaceCount;
|
|
|
|
curSurface->faceStart = aggSurfFaceCount;
|
|
|
|
surfaces.Push(*curSurface);
|
|
|
|
delete curSurface;
|
|
|
|
|
|
|
|
if (uvs.Size() == 0)
|
|
|
|
{ // Needed so that OBJs without UVs can work
|
|
|
|
uvs.Push(FVector2(0.0, 0.0));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-06-06 05:08:05 +00:00
|
|
|
* Parse an x-Dimensional vector
|
|
|
|
*
|
|
|
|
* @tparam T A subclass of TVector2 to be used
|
|
|
|
* @tparam L The length of the vector to parse
|
|
|
|
* @param[out] array The array to append the parsed vector to
|
|
|
|
*/
|
|
|
|
template<typename T, size_t L> void FOBJModel::ParseVector(TArray<T> &array)
|
2018-06-03 07:26:42 +00:00
|
|
|
{
|
2018-11-30 16:12:36 +00:00
|
|
|
float coord[L];
|
2018-06-06 05:08:05 +00:00
|
|
|
for (size_t axis = 0; axis < L; axis++)
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
|
|
|
sc.MustGetFloat();
|
|
|
|
coord[axis] = (float)sc.Float;
|
|
|
|
}
|
2018-06-06 05:08:05 +00:00
|
|
|
T vec(coord);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
array.Push(vec);
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-06-06 05:08:05 +00:00
|
|
|
* Parse a side of a face
|
|
|
|
*
|
|
|
|
* @param[in] sideStr The side definition string
|
|
|
|
* @param[out] face The face to assign the parsed side data to
|
|
|
|
* @param sidx The 0-based index of the side
|
|
|
|
* @return Whether or not the face side was parsed successfully
|
|
|
|
*/
|
|
|
|
bool FOBJModel::ParseFaceSide(const FString &sideStr, OBJFace &face, int sidx)
|
2018-06-03 07:26:42 +00:00
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
OBJFaceSide side;
|
|
|
|
int origIdx;
|
|
|
|
if (sideStr.IndexOf(newSideSep) >= 0)
|
|
|
|
{
|
|
|
|
TArray<FString> sides = sideStr.Split(newSideSep, FString::TOK_KEEPEMPTY);
|
|
|
|
|
|
|
|
if (sides[0].Len() > 0)
|
|
|
|
{
|
|
|
|
origIdx = atoi(sides[0].GetChars());
|
|
|
|
side.vertref = ResolveIndex(origIdx, FaceElement::VertexIndex);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sc.ScriptError("Vertex reference is not optional!");
|
2018-06-06 05:08:05 +00:00
|
|
|
return false;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sides[1].Len() > 0)
|
|
|
|
{
|
|
|
|
origIdx = atoi(sides[1].GetChars());
|
|
|
|
side.uvref = ResolveIndex(origIdx, FaceElement::UVIndex);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
side.uvref = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sides.Size() > 2)
|
|
|
|
{
|
|
|
|
if (sides[2].Len() > 0)
|
|
|
|
{
|
|
|
|
origIdx = atoi(sides[2].GetChars());
|
|
|
|
side.normref = ResolveIndex(origIdx, FaceElement::VNormalIndex);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
side.normref = -1;
|
2018-09-22 14:24:01 +00:00
|
|
|
hasMissingNormals = true;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
side.normref = -1;
|
2018-09-22 14:24:01 +00:00
|
|
|
hasMissingNormals = true;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
origIdx = atoi(sideStr.GetChars());
|
|
|
|
side.vertref = ResolveIndex(origIdx, FaceElement::VertexIndex);
|
|
|
|
side.normref = -1;
|
2018-09-22 14:24:01 +00:00
|
|
|
hasMissingNormals = true;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
side.uvref = -1;
|
|
|
|
}
|
|
|
|
face.sides[sidx] = side;
|
2018-06-06 05:08:05 +00:00
|
|
|
return true;
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Resolve an OBJ index to an absolute index
|
|
|
|
*
|
|
|
|
* OBJ indices are 1-based, and can also be negative
|
|
|
|
*
|
|
|
|
* @param origIndex The original OBJ index to resolve
|
|
|
|
* @param el What type of element the index references
|
|
|
|
* @return The absolute index of the element
|
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
int FOBJModel::ResolveIndex(int origIndex, FaceElement el)
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
if (origIndex > 0)
|
|
|
|
{
|
|
|
|
return origIndex - 1; // OBJ indices start at 1
|
|
|
|
}
|
|
|
|
else if (origIndex < 0)
|
|
|
|
{
|
|
|
|
if (el == FaceElement::VertexIndex)
|
|
|
|
{
|
|
|
|
return verts.Size() + origIndex; // origIndex is negative
|
|
|
|
}
|
|
|
|
else if (el == FaceElement::UVIndex)
|
|
|
|
{
|
|
|
|
return uvs.Size() + origIndex;
|
|
|
|
}
|
|
|
|
else if (el == FaceElement::VNormalIndex)
|
|
|
|
{
|
|
|
|
return norms.Size() + origIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Construct the vertex buffer for this model
|
|
|
|
*
|
|
|
|
* @param renderer A pointer to the model renderer. Used to allocate the vertex buffer.
|
|
|
|
*/
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
void FOBJModel::BuildVertexBuffer(FModelRenderer *renderer)
|
|
|
|
{
|
|
|
|
if (GetVertexBuffer(renderer))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int vbufsize = 0;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < surfaces.Size(); i++)
|
|
|
|
{
|
|
|
|
ConstructSurfaceTris(surfaces[i]);
|
|
|
|
surfaces[i].vbStart = vbufsize;
|
|
|
|
vbufsize += surfaces[i].numTris * 3;
|
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
// Initialize/populate vertFaces
|
|
|
|
if (hasMissingNormals && hasSmoothGroups)
|
|
|
|
{
|
|
|
|
AddVertFaces();
|
|
|
|
}
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
|
|
|
auto vbuf = renderer->CreateVertexBuffer(false,true);
|
|
|
|
SetVertexBuffer(renderer, vbuf);
|
|
|
|
|
|
|
|
FModelVertex *vertptr = vbuf->LockVertexBuffer(vbufsize);
|
|
|
|
|
2018-09-22 16:49:54 +00:00
|
|
|
for (unsigned int i = 0; i < surfaces.Size(); i++)
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
2018-09-22 16:49:54 +00:00
|
|
|
for (unsigned int j = 0; j < surfaces[i].numTris; j++)
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
|
|
|
for (size_t side = 0; side < 3; side++)
|
|
|
|
{
|
|
|
|
FModelVertex *mdv = vertptr +
|
|
|
|
side + j * 3 + // Current surface and previous triangles
|
|
|
|
surfaces[i].vbStart; // Previous surfaces
|
|
|
|
|
|
|
|
OBJFaceSide &curSide = surfaces[i].tris[j].sides[side];
|
|
|
|
|
|
|
|
int vidx = curSide.vertref;
|
2018-06-06 05:08:05 +00:00
|
|
|
int uvidx = (curSide.uvref >= 0 && (unsigned int)curSide.uvref < uvs.Size()) ? curSide.uvref : 0;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
int nidx = curSide.normref;
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
FVector3 curVvec = RealignVector(verts[vidx]);
|
|
|
|
FVector2 curUvec = FixUV(uvs[uvidx]);
|
2018-09-22 14:24:01 +00:00
|
|
|
FVector3 nvec;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
mdv->Set(curVvec.X, curVvec.Y, curVvec.Z, curUvec.X, curUvec.Y);
|
|
|
|
|
|
|
|
if (nidx >= 0 && (unsigned int)nidx < norms.Size())
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
2018-09-22 14:24:01 +00:00
|
|
|
nvec = RealignVector(norms[nidx]);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-09-22 14:24:01 +00:00
|
|
|
if (surfaces[i].tris[j].smoothGroup == 0)
|
|
|
|
{
|
|
|
|
nvec = CalculateNormalFlat(i, j);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nvec = CalculateNormalSmooth(vidx, surfaces[i].tris[j].smoothGroup);
|
|
|
|
}
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
mdv->SetNormal(nvec.X, nvec.Y, nvec.Z);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-06 05:08:05 +00:00
|
|
|
delete[] surfaces[i].tris;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
|
|
|
|
// Destroy vertFaces
|
|
|
|
if (hasMissingNormals && hasSmoothGroups)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < verts.Size(); i++)
|
|
|
|
{
|
|
|
|
vertFaces[i].Clear();
|
|
|
|
}
|
|
|
|
delete[] vertFaces;
|
|
|
|
}
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
vbuf->UnlockVertexBuffer();
|
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Fill in the triangle data for a surface
|
|
|
|
*
|
|
|
|
* @param[in,out] surf The surface to fill in the triangle data for
|
|
|
|
*/
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
void FOBJModel::ConstructSurfaceTris(OBJSurface &surf)
|
2018-06-03 07:26:42 +00:00
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
unsigned int triCount = 0;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
|
|
|
size_t start = surf.faceStart;
|
|
|
|
size_t end = start + surf.numFaces;
|
|
|
|
for (size_t i = start; i < end; i++)
|
|
|
|
{
|
|
|
|
triCount += faces[i].sideCount - 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
surf.numTris = triCount;
|
|
|
|
surf.tris = new OBJFace[triCount];
|
|
|
|
|
|
|
|
for (size_t i = start, triIdx = 0; i < end; i++, triIdx++)
|
|
|
|
{
|
|
|
|
surf.tris[triIdx].sideCount = 3;
|
|
|
|
if (faces[i].sideCount == 3)
|
|
|
|
{
|
2018-09-22 14:24:01 +00:00
|
|
|
surf.tris[triIdx].smoothGroup = faces[i].smoothGroup;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
memcpy(surf.tris[triIdx].sides, faces[i].sides, sizeof(OBJFaceSide) * 3);
|
|
|
|
}
|
|
|
|
else if (faces[i].sideCount == 4) // Triangulate face
|
|
|
|
{
|
|
|
|
OBJFace *triangulated = new OBJFace[2];
|
|
|
|
TriangulateQuad(faces[i], triangulated);
|
|
|
|
memcpy(surf.tris[triIdx].sides, triangulated[0].sides, sizeof(OBJFaceSide) * 3);
|
|
|
|
memcpy(surf.tris[triIdx+1].sides, triangulated[1].sides, sizeof(OBJFaceSide) * 3);
|
|
|
|
delete[] triangulated;
|
|
|
|
triIdx += 1; // Filling out two faces
|
|
|
|
}
|
2018-09-22 14:24:01 +00:00
|
|
|
DPrintf(DMSG_SPAMMY, "Smooth group: %d\n", surf.tris[triIdx].smoothGroup);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Triangulate a 4-sided face
|
|
|
|
*
|
|
|
|
* @param[in] quad The 4-sided face to triangulate
|
|
|
|
* @param[out] tris The resultant triangle data
|
|
|
|
*/
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
void FOBJModel::TriangulateQuad(const OBJFace &quad, OBJFace *tris)
|
2018-06-03 07:26:42 +00:00
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
tris[0].sideCount = 3;
|
2018-09-22 14:24:01 +00:00
|
|
|
tris[0].smoothGroup = quad.smoothGroup;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
tris[1].sideCount = 3;
|
2018-09-22 14:24:01 +00:00
|
|
|
tris[1].smoothGroup = quad.smoothGroup;
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
|
|
|
|
int tsidx[2][3] = {{0, 1, 3}, {1, 2, 3}};
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 2; j++)
|
|
|
|
{
|
|
|
|
tris[j].sides[i].vertref = quad.sides[tsidx[j][i]].vertref;
|
|
|
|
tris[j].sides[i].uvref = quad.sides[tsidx[j][i]].uvref;
|
|
|
|
tris[j].sides[i].normref = quad.sides[tsidx[j][i]].normref;
|
|
|
|
}
|
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-09-22 14:24:01 +00:00
|
|
|
/**
|
|
|
|
* Add the vertices of all surfaces' triangles to the array of vertex->triangle references
|
|
|
|
*/
|
|
|
|
void FOBJModel::AddVertFaces() {
|
|
|
|
// Initialize and populate vertFaces - this array stores references to triangles per vertex
|
|
|
|
vertFaces = new TArray<OBJTriRef>[verts.Size()];
|
2018-09-22 16:49:54 +00:00
|
|
|
for (unsigned int i = 0; i < surfaces.Size(); i++)
|
2018-09-22 14:24:01 +00:00
|
|
|
{
|
2018-09-22 16:49:54 +00:00
|
|
|
for (unsigned int j = 0; j < surfaces[i].numTris; j++)
|
2018-09-22 14:24:01 +00:00
|
|
|
{
|
|
|
|
OBJTriRef otr = OBJTriRef(i, j);
|
|
|
|
for (size_t k = 0; k < surfaces[i].tris[j].sideCount; k++)
|
|
|
|
{
|
|
|
|
int vidx = surfaces[i].tris[j].sides[k].vertref;
|
|
|
|
vertFaces[vidx].Push(otr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Re-align a vector to match MD3 alignment
|
|
|
|
*
|
|
|
|
* @param vecToRealign The vector to re-align
|
|
|
|
* @return The re-aligned vector
|
|
|
|
*/
|
|
|
|
inline FVector3 FOBJModel::RealignVector(FVector3 vecToRealign)
|
|
|
|
{
|
|
|
|
vecToRealign.Z *= -1;
|
|
|
|
return vecToRealign;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fix UV coordinates of a UV vector
|
|
|
|
*
|
|
|
|
* @param vecToRealign The vector to fix
|
|
|
|
* @return The fixed UV coordinate vector
|
|
|
|
*/
|
|
|
|
inline FVector2 FOBJModel::FixUV(FVector2 vecToRealign)
|
|
|
|
{
|
|
|
|
vecToRealign.Y *= -1;
|
|
|
|
return vecToRealign;
|
|
|
|
}
|
|
|
|
|
2018-09-22 14:24:01 +00:00
|
|
|
/**
|
|
|
|
* Calculate the surface normal for a triangle
|
|
|
|
*
|
|
|
|
* @param surfIdx The surface index
|
|
|
|
* @param triIdx The triangle Index
|
|
|
|
* @return The surface normal vector
|
|
|
|
*/
|
|
|
|
FVector3 FOBJModel::CalculateNormalFlat(unsigned int surfIdx, unsigned int triIdx)
|
|
|
|
{
|
|
|
|
// https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal
|
|
|
|
int curVert = surfaces[surfIdx].tris[triIdx].sides[0].vertref;
|
|
|
|
int nextVert = surfaces[surfIdx].tris[triIdx].sides[2].vertref;
|
|
|
|
int lastVert = surfaces[surfIdx].tris[triIdx].sides[1].vertref;
|
|
|
|
|
|
|
|
// Cross-multiply the U-vector and V-vector
|
|
|
|
FVector3 curVvec = RealignVector(verts[curVert]);
|
|
|
|
FVector3 uvec = RealignVector(verts[nextVert]) - curVvec;
|
|
|
|
FVector3 vvec = RealignVector(verts[lastVert]) - curVvec;
|
|
|
|
|
|
|
|
return uvec ^ vvec;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the surface normal for a triangle
|
|
|
|
*
|
|
|
|
* @param otr A reference to the surface, and a triangle within that surface, as an OBJTriRef
|
|
|
|
* @return The surface normal vector
|
|
|
|
*/
|
|
|
|
FVector3 FOBJModel::CalculateNormalFlat(OBJTriRef otr)
|
|
|
|
{
|
|
|
|
return CalculateNormalFlat(otr.surf, otr.tri);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the normal of a vertex in a specific smooth group
|
|
|
|
*
|
|
|
|
* @param vidx The index of the vertex in the array of vertices
|
|
|
|
* @param smoothGroup The smooth group number
|
|
|
|
*/
|
|
|
|
FVector3 FOBJModel::CalculateNormalSmooth(unsigned int vidx, unsigned int smoothGroup)
|
|
|
|
{
|
|
|
|
unsigned int connectedFaces = 0;
|
|
|
|
TArray<OBJTriRef>& vTris = vertFaces[vidx];
|
|
|
|
|
|
|
|
FVector3 vNormal(0,0,0);
|
|
|
|
for (size_t face = 0; face < vTris.Size(); face++)
|
|
|
|
{
|
|
|
|
OBJFace& tri = surfaces[vTris[face].surf].tris[vTris[face].tri];
|
|
|
|
if (tri.smoothGroup == smoothGroup)
|
|
|
|
{
|
|
|
|
FVector3 fNormal = CalculateNormalFlat(vTris[face]);
|
|
|
|
connectedFaces += 1;
|
|
|
|
vNormal += fNormal;
|
|
|
|
}
|
|
|
|
}
|
2018-09-22 16:49:54 +00:00
|
|
|
vNormal /= (float)connectedFaces;
|
2018-09-22 14:24:01 +00:00
|
|
|
return vNormal;
|
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Find the index of the frame with the given name
|
|
|
|
*
|
|
|
|
* OBJ models are not animated, so this always returns 0
|
|
|
|
*
|
|
|
|
* @param name The name of the frame
|
|
|
|
* @return The index of the frame
|
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
int FOBJModel::FindFrame(const char* name)
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
return 0; // OBJs are not animated.
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Render the model
|
|
|
|
*
|
|
|
|
* @param renderer The model renderer
|
|
|
|
* @param skin The loaded skin for the surface
|
|
|
|
* @param frameno Unused
|
|
|
|
* @param frameno2 Unused
|
|
|
|
* @param inter Unused
|
|
|
|
* @param translation The translation for the skin
|
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
void FOBJModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frameno, int frameno2, double inter, int translation)
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
for (unsigned int i = 0; i < surfaces.Size(); i++)
|
|
|
|
{
|
|
|
|
OBJSurface *surf = &surfaces[i];
|
2018-06-03 07:26:42 +00:00
|
|
|
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
FTexture *userSkin = skin;
|
|
|
|
if (!userSkin)
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
2018-12-07 01:53:18 +00:00
|
|
|
userSkin = TexMan.GetTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
else if (surf->skin.isValid())
|
|
|
|
{
|
2018-12-07 01:53:18 +00:00
|
|
|
userSkin = TexMan.GetTexture(surf->skin, true);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-06 05:08:05 +00:00
|
|
|
|
|
|
|
// Still no skin after checking for one?
|
|
|
|
if (!userSkin)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
renderer->SetMaterial(userSkin, false, translation);
|
2018-06-06 05:08:05 +00:00
|
|
|
GetVertexBuffer(renderer)->SetupFrame(renderer, surf->vbStart, surf->vbStart, surf->numTris * 3);
|
|
|
|
renderer->DrawArrays(0, surf->numTris * 3);
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Pre-cache skins for the model
|
|
|
|
*
|
|
|
|
* @param hitlist The list of textures
|
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
void FOBJModel::AddSkins(uint8_t* hitlist)
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
for (size_t i = 0; i < surfaces.Size(); i++)
|
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid())
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
{
|
2018-06-06 05:08:05 +00:00
|
|
|
// Precache skins manually reassigned by the user.
|
|
|
|
// On OBJs with lots of skins, such as Doom map OBJs exported from GZDB,
|
|
|
|
// there may be too many skins for the user to manually change, unless
|
|
|
|
// the limit is bumped or surfaceskinIDs is changed to a TArray<FTextureID>.
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat;
|
2018-06-06 05:08:05 +00:00
|
|
|
return; // No need to precache skin that was replaced
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
OBJSurface * surf = &surfaces[i];
|
|
|
|
if (surf->skin.isValid())
|
|
|
|
{
|
|
|
|
hitlist[surf->skin.GetIndex()] |= FTextureManager::HIT_Flat;
|
|
|
|
}
|
|
|
|
}
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 05:08:05 +00:00
|
|
|
/**
|
|
|
|
* Remove the data that was loaded
|
|
|
|
*/
|
2018-06-03 07:26:42 +00:00
|
|
|
FOBJModel::~FOBJModel()
|
|
|
|
{
|
Fix rendering and parsing of OBJ models
Create a new surface for each 'usemtl' statement in the OBJ file, and fix memory errors caused by TriangulateQuad.
Calculate missing normals, and fix incorrect UV coordinates
Fix construction of vertex buffer for objects with multiple surfaces
Localize curMtl, curSurface, aggSurfFaceCount, and curSurfFaceCount to FOBJModel::Load(), since they are not used anywhere else.
Fix parsing of OBJs without UV references
Internally, I replaced hashtag line comments with C-style line comments, and I replaced each forward slash with newSideSep.
If no UV coordinates are available, add a default vector of (0,0).
Also, remove "this->" from ResolveIndex to make the code a bit cleaner, and fix a minor garbage issue I failed to notice earlier (normref would pick up garbage if there was no normal reference).
Ensure usemtl statements remain intact
It may be a bit inefficient, but I tried modifying the buffer directly, and I got memory corruption errors. In this case, it's a lot better to be safe than sorry.
2018-06-03 08:11:38 +00:00
|
|
|
verts.Clear();
|
|
|
|
norms.Clear();
|
|
|
|
uvs.Clear();
|
|
|
|
faces.Clear();
|
|
|
|
surfaces.Clear();
|
2018-06-03 07:26:42 +00:00
|
|
|
}
|