Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / 3d / pipeline_max / builtin / geom_object.cpp
blob76bb5a4aacc94381bbf2bb28b3a50e6e45162f78
1 /**
2 * \file geom_object.cpp
3 * \brief CGeomGeomObject
4 * \date 2012-08-22 08:58GMT
5 * \author Jan Boon (Kaetemi)
6 * CGeomGeomObject
7 */
9 /*
10 * Copyright (C) 2012 by authors
12 * This file is part of RYZOM CORE PIPELINE.
13 * RYZOM CORE PIPELINE is free software: you can redistribute it
14 * and/or modify it under the terms of the GNU Affero General Public
15 * License as published by the Free Software Foundation, either
16 * version 3 of the License, or (at your option) any later version.
18 * RYZOM CORE PIPELINE is distributed in the hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
23 * You should have received a copy of the GNU Affero General Public
24 * License along with RYZOM CORE PIPELINE. If not, see
25 * <http://www.gnu.org/licenses/>.
28 #include <nel/misc/types_nl.h>
29 #include "geom_object.h"
31 // STL includes
33 // NeL includes
34 // #include <nel/misc/debug.h>
36 // Project includes
38 // using namespace std;
39 // using namespace NLMISC;
41 namespace PIPELINE {
42 namespace MAX {
43 namespace BUILTIN {
45 #define PMB_GEOM_UNKNOWN0900_CHUNK_ID 0x0900
46 #define PMB_GEOM_BUFFERS_CHUNK_ID 0x08fe
48 CGeomObject::CGeomObject(CScene *scene) : CObject(scene), m_Unknown0900(NULL), m_GeomBuffers(NULL)
53 CGeomObject::~CGeomObject()
55 if (!m_ChunksOwnsPointers)
57 m_Unknown0900 = NULL;
58 m_GeomBuffers = NULL;
62 const ucstring CGeomObject::DisplayName = ucstring("GeomObject");
63 const char *CGeomObject::InternalName = "GeomObject";
64 const char *CGeomObject::InternalNameUnknown = "GeomObjectUnknown";
65 const NLMISC::CClassId CGeomObject::ClassId = NLMISC::CClassId(0x37097c44, 0x38aa3f24); /* Not official, please correct */
66 const TSClassId CGeomObject::SuperClassId = 0x00000010;
67 const CGeomObjectClassDesc GeomObjectClassDesc(&DllPluginDescBuiltin);
68 const CGeomObjectSuperClassDesc GeomObjectSuperClassDesc(&GeomObjectClassDesc);
70 void CGeomObject::parse(uint16 version, uint filter)
72 if (filter == 0)
74 CObject::parse(version);
76 else if (filter == PMB_GEOM_OBJECT_PARSE_FILTER)
78 if (!m_ChunksOwnsPointers)
80 m_Unknown0900 = getChunk(PMB_GEOM_UNKNOWN0900_CHUNK_ID);
81 m_GeomBuffers = static_cast<STORAGE::CGeomBuffers *>(getChunk(PMB_GEOM_BUFFERS_CHUNK_ID));
86 void CGeomObject::clean()
88 CObject::clean();
91 void CGeomObject::build(uint16 version, uint filter)
93 if (filter == 0)
95 CObject::build(version);
97 else if (filter == PMB_GEOM_OBJECT_PARSE_FILTER)
99 if (m_Unknown0900) putChunk(PMB_GEOM_UNKNOWN0900_CHUNK_ID, m_Unknown0900);
100 if (m_GeomBuffers) putChunk(PMB_GEOM_BUFFERS_CHUNK_ID, m_GeomBuffers);
104 void CGeomObject::disown()
106 m_Unknown0900 = NULL;
107 m_GeomBuffers = NULL;
108 CObject::disown();
111 void CGeomObject::init()
113 CObject::init();
116 bool CGeomObject::inherits(const NLMISC::CClassId classId) const
118 if (classId == classDesc()->classId()) return true;
119 return CObject::inherits(classId);
122 const ISceneClassDesc *CGeomObject::classDesc() const
124 return &GeomObjectClassDesc;
127 void CGeomObject::toStringLocal(std::ostream &ostream, const std::string &pad, uint filter) const
129 if (filter == 0)
131 CObject::toStringLocal(ostream, pad);
133 else if (filter == PMB_GEOM_OBJECT_PARSE_FILTER)
135 std::string padpad = pad + "\t";
136 if (m_Unknown0900)
138 ostream << "\n" << pad << "GeomObject Unknown 0x0900: ";
139 m_Unknown0900->toString(ostream, padpad);
141 if (m_GeomBuffers)
143 ostream << "\n" << pad << "GeomBuffers: ";
144 m_GeomBuffers->toString(ostream, padpad);
149 inline uint32 rrsub(uint32 v, uint32 size)
151 if (v) return v - 1;
152 return size - 1;
155 inline uint32 rradd(uint32 v, uint32 size)
157 uint32 vp = v + 1;
158 if (vp != size) return vp;
159 return 0;
162 void CGeomObject::triangulatePolyFace(std::vector<STORAGE::CGeomTriIndex> &triangles, const STORAGE::CGeomPolyFaceInfo &polyFace)
164 nlassert(polyFace.Vertices.size() >= 3);
165 nlassert(polyFace.Triangulation.size() == polyFace.Vertices.size() - 3);
166 uint nbVert = polyFace.Vertices.size();
167 uint nbCuts = polyFace.Triangulation.size();
168 uint nbTriangles = 0;
170 // This code creates a matrix, aka a table, of all possible paths
171 // that can be traveled to get directly from one vertex to another
172 // over an egde.
173 // Outer edges of the polygon are one-way, backwards.
174 // Cut edges can be traveled both ways.
175 // Each edge direction can only be traveled by one triangle.
176 // Ingenious, if I may say so myself.
177 // Bad performance by std::vector, though.
178 std::vector<std::vector<bool> > from_to;
179 from_to.resize(nbVert);
180 for (uint i = 0; i < nbVert; ++i)
182 from_to[i].resize(nbVert);
183 for (uint j = 0; j < nbVert; ++j)
185 from_to[i][j] = false;
187 // Can travel backwards over the outer edge
188 from_to[i][rrsub(i, nbVert)] = true;
190 for (uint i = 0; i < nbCuts; ++i)
192 // Can travel both ways over cuts, but the first direction is handled directly!
193 // from_to[polyFace.Triangulation[i].first][polyFace.Triangulation[i].second] = true;
194 from_to[polyFace.Triangulation[i].second][polyFace.Triangulation[i].first] = true;
196 // Triangulate all cuts, this assumes cuts are in the direction
197 // of a triangle that is not already handled by another cut...
198 for (uint i = 0; i < nbCuts; ++i)
200 uint32 a = polyFace.Triangulation[i].first;
201 uint32 b = polyFace.Triangulation[i].second;
202 // from_to[polyFace.Triangulation[i].first][polyFace.Triangulation[i].second] = false; // handled!
203 // Try to find a path that works
204 for (uint c = 0; c < nbVert; ++c)
206 // Can we make a triangle
207 if (from_to[b][c] && from_to[c][a])
209 STORAGE::CGeomTriIndex tri;
210 tri.a = polyFace.Vertices[c];
211 tri.b = polyFace.Vertices[b];
212 tri.c = polyFace.Vertices[a];
213 triangles.push_back(tri);
214 ++nbTriangles;
215 // nldebug("add tri from cut");
216 from_to[b][c] = false;
217 from_to[c][a] = false;
218 break;
222 // Find... The Last Triangle
223 for (uint a = 0; a < nbVert; ++a)
225 uint b = rrsub(a, nbVert);
226 // Can we still travel backwards over the outer edge?
227 if (from_to[a][b])
229 for (uint c = 0; c < nbVert; ++c)
231 // Can we make a triangle
232 if (from_to[b][c] && from_to[c][a])
234 STORAGE::CGeomTriIndex tri;
235 tri.a = polyFace.Vertices[c];
236 tri.b = polyFace.Vertices[b];
237 tri.c = polyFace.Vertices[a];
238 triangles.push_back(tri);
239 ++nbTriangles;
240 // nldebug("add final tri");
241 from_to[b][c] = false;
242 from_to[c][a] = false;
243 break;
248 // nldebug("triangles: %i", nbTriangles);
249 // nldebug("cuts: %i", nbCuts);
250 nlassert(nbTriangles == nbCuts + 1);
253 IStorageObject *CGeomObject::createChunkById(uint16 id, bool container)
255 switch (id)
257 case PMB_GEOM_UNKNOWN0900_CHUNK_ID:
258 return new CStorageArray<sint32>();
259 case PMB_GEOM_BUFFERS_CHUNK_ID:
260 return new STORAGE::CGeomBuffers();
262 return CObject::createChunkById(id, container);
265 } /* namespace BUILTIN */
266 } /* namespace MAX */
267 } /* namespace PIPELINE */
269 /* end of file */