mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
load obj files directly into PandaNodes for performance
This commit is contained in:
parent
6f987a585d
commit
b3b2308c6c
@ -328,7 +328,7 @@ set_primitive(int i, const GeomPrimitive *primitive) {
|
||||
nassertv(cdata->_primitive_type == PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
// They also should have the a compatible shade model.
|
||||
// They also should have a compatible shade model.
|
||||
CPT(GeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||
nassertv_always(compat != (GeomPrimitive *)NULL);
|
||||
|
||||
@ -374,7 +374,7 @@ add_primitive(const GeomPrimitive *primitive) {
|
||||
nassertv(cdata->_primitive_type == PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
// They also should have the a compatible shade model.
|
||||
// They also should have a compatible shade model.
|
||||
CPT(GeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||
nassertv_always(compat != (GeomPrimitive *)NULL);
|
||||
|
||||
@ -591,6 +591,19 @@ rotate_in_place() {
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (cdata->_shade_model) {
|
||||
case SM_flat_first_vertex:
|
||||
cdata->_shade_model = SM_flat_last_vertex;
|
||||
break;
|
||||
|
||||
case SM_flat_last_vertex:
|
||||
cdata->_shade_model = SM_flat_first_vertex;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
clear_cache_stage(current_thread);
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
||||
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
||||
triangulator.h triangulator.I \
|
||||
triangulator3.h triangulator3.I \
|
||||
unionBoundingVolume.h unionBoundingVolume.I
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
@ -66,6 +67,7 @@
|
||||
stackedPerlinNoise2.cxx \
|
||||
stackedPerlinNoise3.cxx \
|
||||
triangulator.cxx \
|
||||
triangulator3.cxx \
|
||||
unionBoundingVolume.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
@ -94,6 +96,7 @@
|
||||
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
||||
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
||||
triangulator.h triangulator.I \
|
||||
triangulator3.h triangulator3.I \
|
||||
unionBoundingVolume.h unionBoundingVolume.I
|
||||
|
||||
|
||||
|
@ -16,3 +16,4 @@
|
||||
#include "stackedPerlinNoise2.cxx"
|
||||
#include "stackedPerlinNoise3.cxx"
|
||||
#include "triangulator.cxx"
|
||||
#include "triangulator3.cxx"
|
||||
|
@ -118,14 +118,27 @@ void Triangulator::
|
||||
triangulate() {
|
||||
_result.clear();
|
||||
|
||||
// Make sure our index numbers are reasonable.
|
||||
cleanup_polygon_indices(_polygon);
|
||||
Holes::iterator hi;
|
||||
for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
|
||||
cleanup_polygon_indices(*hi);
|
||||
}
|
||||
|
||||
if (_polygon.size() < 3) {
|
||||
// Degenerate case.
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the list of segments.
|
||||
seg.clear();
|
||||
seg.push_back(segment_t()); // we don't use the first entry.
|
||||
make_segment(_polygon, true);
|
||||
|
||||
Holes::const_iterator hi;
|
||||
for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
|
||||
make_segment(*hi, false);
|
||||
if ((*hi).size() >= 3) {
|
||||
make_segment(*hi, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle the segment index.
|
||||
@ -151,6 +164,7 @@ triangulate() {
|
||||
*/
|
||||
choose_idx = 0;
|
||||
|
||||
/*
|
||||
//cerr << "got " << num_segments << " segments\n";
|
||||
for (i = 1; i < (int)seg.size(); ++i) {
|
||||
segment_t &s = seg[i];
|
||||
@ -158,6 +172,7 @@ triangulate() {
|
||||
printf(" root0 = %d, root1 = %d\n", s.root0, s.root1);
|
||||
printf(" next = %d, prev = %d\n", s.next, s.prev);
|
||||
}
|
||||
*/
|
||||
|
||||
while (construct_trapezoids(num_segments) != 0) {
|
||||
// If there's an error, re-shuffle the index and try again.
|
||||
@ -262,6 +277,43 @@ get_triangle_v2(int n) const {
|
||||
return _result[n]._v2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator::cleanup_polygon_indices
|
||||
// Access: Protected
|
||||
// Description: Removes any invalid index numbers from the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Triangulator::
|
||||
cleanup_polygon_indices(vector_int &polygon) {
|
||||
// First, check for index bounds.
|
||||
size_t pi = 0;
|
||||
while (pi < polygon.size()) {
|
||||
if (polygon[pi] >= 0 && polygon[pi] < _vertices.size()) {
|
||||
// This vertex is OK.
|
||||
++pi;
|
||||
} else {
|
||||
// This index is out-of-bounds; remove it.
|
||||
polygon.erase(_polygon.begin() + pi);
|
||||
}
|
||||
}
|
||||
|
||||
// Now, remove any consecutive repeated vertices.
|
||||
pi = 1;
|
||||
while (pi < polygon.size()) {
|
||||
if (_vertices[polygon[pi]] != _vertices[polygon[pi - 1]]) {
|
||||
// This vertex is OK.
|
||||
++pi;
|
||||
} else {
|
||||
// This vertex repeats the previous one; remove it.
|
||||
polygon.erase(_polygon.begin() + pi);
|
||||
}
|
||||
}
|
||||
|
||||
if (polygon.size() > 1 && _vertices[polygon.back()] == _vertices[_polygon.front()]) {
|
||||
// The last vertex repeats the first one; remove it.
|
||||
polygon.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The remainder of the code in this file is adapted more or less from
|
||||
// the C code published with the referenced paper.
|
||||
|
@ -31,9 +31,8 @@
|
||||
//
|
||||
// http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html
|
||||
//
|
||||
// It works strictly on 2-d points. You'll have to
|
||||
// convert your polygon into a plane if you have 3-d
|
||||
// points.
|
||||
// It works strictly on 2-d points. See Triangulator3
|
||||
// for 3-d points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_MATHUTIL Triangulator {
|
||||
PUBLISHED:
|
||||
@ -61,7 +60,9 @@ PUBLISHED:
|
||||
int get_triangle_v1(int n) const;
|
||||
int get_triangle_v2(int n) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void cleanup_polygon_indices(vector_int &polygon);
|
||||
|
||||
typedef pvector<LPoint2d> Vertices;
|
||||
Vertices _vertices;
|
||||
|
||||
|
61
panda/src/mathutil/triangulator3.I
Executable file
61
panda/src/mathutil/triangulator3.I
Executable file
@ -0,0 +1,61 @@
|
||||
// Filename: triangulator3.I
|
||||
// Created by: drose (03Jan13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::add_vertex
|
||||
// Access: Published
|
||||
// Description: Adds a new vertex to the vertex pool. Returns the
|
||||
// vertex index number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int Triangulator3::
|
||||
add_vertex(double x, double y, double z) {
|
||||
return add_vertex(LPoint3d(x, y, z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices in the pool. Note
|
||||
// that the Triangulator might append new vertices, in
|
||||
// addition to those added by the user, if any of the
|
||||
// polygon is self-intersecting, or if any of the holes
|
||||
// intersect some part of the polygon edges.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int Triangulator3::
|
||||
get_num_vertices() const {
|
||||
return _vertices3.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the nth vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LPoint3d &Triangulator3::
|
||||
get_vertex(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_vertices3.size(), LPoint3d::zero());
|
||||
return _vertices3[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::get_plane
|
||||
// Access: Published
|
||||
// Description: Returns the plane of the polygon. This is only
|
||||
// available after calling triangulate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LPlaned &Triangulator3::
|
||||
get_plane() const {
|
||||
return _plane;
|
||||
}
|
112
panda/src/mathutil/triangulator3.cxx
Executable file
112
panda/src/mathutil/triangulator3.cxx
Executable file
@ -0,0 +1,112 @@
|
||||
// Filename: triangulator3.cxx
|
||||
// Created by: drose (03Jan13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "triangulator3.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Triangulator3::
|
||||
Triangulator3() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::clear
|
||||
// Access: Published
|
||||
// Description: Removes all vertices and polygon specifications from
|
||||
// the Triangulator, and prepares it to start over.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Triangulator3::
|
||||
clear() {
|
||||
_vertices3.clear();
|
||||
_plane = LPlaned();
|
||||
Triangulator::clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::add_vertex
|
||||
// Access: Published
|
||||
// Description: Adds a new vertex to the vertex pool. Returns the
|
||||
// vertex index number.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Triangulator3::
|
||||
add_vertex(const LPoint3d &point) {
|
||||
int index = (int)_vertices3.size();
|
||||
_vertices3.push_back(point);
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Triangulator3::triangulate
|
||||
// Access: Published
|
||||
// Description: Does the work of triangulating the specified polygon.
|
||||
// After this call, you may retrieve the new triangles
|
||||
// one at a time by iterating through
|
||||
// get_triangle_v0/1/2().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Triangulator3::
|
||||
triangulate() {
|
||||
_result.clear();
|
||||
|
||||
if (_polygon.size() < 3) {
|
||||
// Degenerate case.
|
||||
return;
|
||||
}
|
||||
|
||||
// First, determine the polygon normal.
|
||||
LNormald normal = LNormald::zero();
|
||||
|
||||
// Project the polygon into each of the three major planes and
|
||||
// calculate the area of each 2-d projection. This becomes the
|
||||
// polygon normal. This works because the ratio between these
|
||||
// different areas corresponds to the angle at which the polygon is
|
||||
// tilted toward each plane.
|
||||
size_t num_verts = _polygon.size();
|
||||
for (size_t i = 0; i < num_verts; i++) {
|
||||
int i0 = _polygon[i];
|
||||
int i1 = _polygon[(i + 1) % num_verts];;;;
|
||||
nassertv(i0 >= 0 && i0 < (int)_vertices3.size() &&
|
||||
i1 >= 0 && i1 < (int)_vertices3.size());
|
||||
const LPoint3d &p0 = _vertices3[i0];
|
||||
const LPoint3d &p1 = _vertices3[i1];
|
||||
normal[0] += p0[1] * p1[2] - p0[2] * p1[1];
|
||||
normal[1] += p0[2] * p1[0] - p0[0] * p1[2];
|
||||
normal[2] += p0[0] * p1[1] - p0[1] * p1[0];
|
||||
}
|
||||
|
||||
if (!normal.normalize()) {
|
||||
// The polygon is degenerate: it has zero area in each plane. In
|
||||
// this case, the triangulation result produces no triangles
|
||||
// anyway.
|
||||
return;
|
||||
}
|
||||
|
||||
_plane = LPlaned(normal, _vertices3[0]);
|
||||
|
||||
// Now determine the matrix to project each of the vertices into
|
||||
// this 2-d plane.
|
||||
LMatrix4d mat;
|
||||
heads_up(mat, _vertices3[1] - _vertices3[2], normal, CS_zup_right);
|
||||
mat.set_row(3, _vertices3[0]);
|
||||
mat.invert_in_place();
|
||||
|
||||
_vertices.clear();
|
||||
for (size_t i = 0; i < _vertices3.size(); i++) {
|
||||
LPoint3d p = _vertices3[i] * mat;
|
||||
_vertices.push_back(LPoint2d(p[0], p[1]));
|
||||
}
|
||||
Triangulator::triangulate();
|
||||
}
|
55
panda/src/mathutil/triangulator3.h
Executable file
55
panda/src/mathutil/triangulator3.h
Executable file
@ -0,0 +1,55 @@
|
||||
// Filename: triangulator3.h
|
||||
// Created by: drose (03Jan13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIANGULATOR3_H
|
||||
#define TRIANGULATOR3_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "triangulator.h"
|
||||
#include "plane.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Triangulator3
|
||||
// Description : This is an extension of Triangulator to handle
|
||||
// polygons with three-dimensional points. It assumes
|
||||
// all of the points lie in a single plane, and
|
||||
// internally projects the supplied points into 2-D for
|
||||
// passing to the underlying Triangulator object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_MATHUTIL Triangulator3 : public Triangulator {
|
||||
PUBLISHED:
|
||||
Triangulator3();
|
||||
|
||||
void clear();
|
||||
int add_vertex(const LPoint3d &point);
|
||||
INLINE int add_vertex(double x, double y, double z);
|
||||
|
||||
INLINE int get_num_vertices() const;
|
||||
INLINE const LPoint3d &get_vertex(int n) const;
|
||||
MAKE_SEQ(get_vertices, get_num_vertices, get_vertex);
|
||||
|
||||
void triangulate();
|
||||
INLINE const LPlaned &get_plane() const;
|
||||
|
||||
private:
|
||||
typedef pvector<LPoint3d> Vertices3;
|
||||
Vertices3 _vertices3;
|
||||
|
||||
LPlaned _plane;
|
||||
};
|
||||
|
||||
#include "triangulator3.I"
|
||||
|
||||
#endif
|
@ -402,13 +402,21 @@ string_to_double(const string &str, double &result) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: string_to_float
|
||||
// Description: Another flavor of string_to_float(), this one
|
||||
// returns true if the string is a perfectly valid
|
||||
// number (and sets result to that value), or false
|
||||
// otherwise.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
string_to_float(const string &str, PN_stdfloat &result) {
|
||||
string_to_float(const string &str, float &result) {
|
||||
string tail;
|
||||
result = (float)string_to_double(str, tail);
|
||||
return tail.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: string_to_stdfloat
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
string_to_stdfloat(const string &str, PN_stdfloat &result) {
|
||||
string tail;
|
||||
result = (PN_stdfloat)string_to_double(str, tail);
|
||||
return tail.empty();
|
||||
|
@ -58,7 +58,8 @@ EXPCL_PANDA_PUTIL int string_to_int(const string &str, string &tail);
|
||||
EXPCL_PANDA_PUTIL bool string_to_int(const string &str, int &result);
|
||||
EXPCL_PANDA_PUTIL double string_to_double(const string &str, string &tail);
|
||||
EXPCL_PANDA_PUTIL bool string_to_double(const string &str, double &result);
|
||||
EXPCL_PANDA_PUTIL bool string_to_float(const string &str, PN_stdfloat &result);
|
||||
EXPCL_PANDA_PUTIL bool string_to_float(const string &str, float &result);
|
||||
EXPCL_PANDA_PUTIL bool string_to_stdfloat(const string &str, PN_stdfloat &result);
|
||||
|
||||
// Convenience function to make a string from anything that has an
|
||||
// ostream operator.
|
||||
|
@ -101,6 +101,22 @@ supports_compressed() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SomethingToEggConverter::supports_convert_to_node
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns true if this converter can directly convert
|
||||
// the model type to internal Panda memory structures,
|
||||
// given the indicated options, or false otherwise. If
|
||||
// this returns true, then convert_to_node() may be
|
||||
// called to perform the conversion, which may be faster
|
||||
// than calling convert_file() if the ultimate goal is a
|
||||
// PandaNode anyway.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool SomethingToEggConverter::
|
||||
supports_convert_to_node(const LoaderOptions &options) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SomethingToEggConverter::get_input_units
|
||||
// Access: Public, Virtual
|
||||
@ -115,6 +131,20 @@ get_input_units() {
|
||||
return DU_invalid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SomethingToEggConverter::convert_to_node
|
||||
// Access: Public, Virtual
|
||||
// Description: Reads the input file and directly produces a
|
||||
// ready-to-render model file as a PandaNode. Returns
|
||||
// NULL on failure, or if it is not supported. (This
|
||||
// functionality is not supported by all converter
|
||||
// types; see supports_convert_to_node()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode) SomethingToEggConverter::
|
||||
convert_to_node(const LoaderOptions &options, const Filename &filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SomethingToEggConverter::handle_external_reference
|
||||
// Access: Public
|
||||
|
@ -23,9 +23,11 @@
|
||||
#include "pathReplace.h"
|
||||
#include "pointerTo.h"
|
||||
#include "distanceUnit.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
class EggData;
|
||||
class EggGroupNode;
|
||||
class LoaderOptions;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SomethingToEggConverter
|
||||
@ -103,8 +105,10 @@ public:
|
||||
virtual string get_extension() const=0;
|
||||
virtual string get_additional_extensions() const;
|
||||
virtual bool supports_compressed() const;
|
||||
virtual bool supports_convert_to_node(const LoaderOptions &options) const;
|
||||
|
||||
virtual bool convert_file(const Filename &filename)=0;
|
||||
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
|
||||
virtual DistanceUnit get_input_units();
|
||||
|
||||
bool handle_external_reference(EggGroupNode *egg_parent,
|
||||
|
@ -15,11 +15,11 @@
|
||||
|
||||
#define SOURCES \
|
||||
config_objegg.cxx config_objegg.h \
|
||||
objToEggConverter.cxx objToEggConverter.h \
|
||||
objToEggConverter.cxx objToEggConverter.h objToEggConverter.I \
|
||||
eggToObjConverter.cxx eggToObjConverter.h
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
objToEggConverter.h \
|
||||
objToEggConverter.h objToEggConverter.I \
|
||||
eggToObjConverter.h
|
||||
|
||||
#end ss_lib_target
|
||||
|
63
pandatool/src/objegg/objToEggConverter.I
Executable file
63
pandatool/src/objegg/objToEggConverter.I
Executable file
@ -0,0 +1,63 @@
|
||||
// Filename: objToEggConverter.I
|
||||
// Created by: drose (03Jan13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ObjToEggConverter::VertexEntry::operator <
|
||||
// Access: Public
|
||||
// Description: Provides a unique but arbitrary ordering for
|
||||
// VertexEntry objects in a map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ObjToEggConverter::VertexEntry::
|
||||
operator < (const VertexEntry &other) const {
|
||||
if (_vi != other._vi) {
|
||||
return _vi < other._vi;
|
||||
}
|
||||
if (_vti != other._vti) {
|
||||
return _vti < other._vti;
|
||||
}
|
||||
|
||||
// It's important that these two tests are made last, so we can find
|
||||
// the first vertex that has any normal but also matches the above
|
||||
// properties.
|
||||
if (_vni != other._vni) {
|
||||
return _vni < other._vni;
|
||||
}
|
||||
if (_synth_vni != other._synth_vni) {
|
||||
return _synth_vni < other._synth_vni;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ObjToEggConverter::VertexEntry::operator ==
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ObjToEggConverter::VertexEntry::
|
||||
operator == (const VertexEntry &other) const {
|
||||
return (_vi == other._vi && _vti == other._vti &&
|
||||
_vni == other._vni && _synth_vni == other._synth_vni);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ObjToEggConverter::VertexEntry::matches_except_normal
|
||||
// Access: Public
|
||||
// Description: Returns true if all the properties except _vni and _synth_vni
|
||||
// are equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ObjToEggConverter::VertexEntry::
|
||||
matches_except_normal(const VertexEntry &other) const {
|
||||
return (_vi == other._vi && _vti == other._vti);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,11 @@
|
||||
#include "somethingToEggConverter.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggGroup.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "geomVertexWriter.h"
|
||||
#include "geomPrimitive.h"
|
||||
#include "geomNode.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ObjToEggConverter
|
||||
@ -36,8 +41,10 @@ public:
|
||||
virtual string get_name() const;
|
||||
virtual string get_extension() const;
|
||||
virtual bool supports_compressed() const;
|
||||
virtual bool supports_convert_to_node(const LoaderOptions &options) const;
|
||||
|
||||
virtual bool convert_file(const Filename &filename);
|
||||
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
|
||||
|
||||
protected:
|
||||
bool process(const Filename &filename);
|
||||
@ -47,22 +54,94 @@ protected:
|
||||
bool process_v(vector_string &words);
|
||||
bool process_vt(vector_string &words);
|
||||
bool process_xvt(vector_string &words);
|
||||
bool process_xvc(vector_string &words);
|
||||
bool process_vn(vector_string &words);
|
||||
bool process_f(vector_string &words);
|
||||
bool process_g(vector_string &words);
|
||||
|
||||
EggVertex *get_vertex(int n);
|
||||
EggVertex *get_face_vertex(const string &face_reference);
|
||||
|
||||
bool process_node(const Filename &filename);
|
||||
bool process_line_node(const string &line);
|
||||
|
||||
bool process_f_node(vector_string &words);
|
||||
bool process_g_node(vector_string &words);
|
||||
|
||||
void generate_points();
|
||||
int add_synth_normal(const LVecBase3 &normal);
|
||||
|
||||
// Read from the obj file.
|
||||
int _line_number;
|
||||
int _vi, _vti, _xvti, _vni;
|
||||
typedef pvector<LVecBase4> Vec4Table;
|
||||
typedef pvector<LVecBase3> Vec3Table;
|
||||
typedef pvector<LVecBase2> Vec2Table;
|
||||
typedef pmap<LVecBase3, int> UniqueVec3Table;
|
||||
|
||||
Vec4Table _v_table;
|
||||
Vec3Table _vn_table, _rgb_table;
|
||||
Vec3Table _vt_table;
|
||||
Vec2Table _xvt_table;
|
||||
Vec3Table _synth_vn_table;
|
||||
UniqueVec3Table _unique_synth_vn_table;
|
||||
LVecBase2 _ref_plane_res;
|
||||
bool _v4_given, _vt3_given;
|
||||
bool _f_given;
|
||||
|
||||
pset<string> _ignored_tags;
|
||||
|
||||
// Structures filled when creating an egg file.
|
||||
PT(EggVertexPool) _vpool;
|
||||
PT(EggGroup) _root_group;
|
||||
EggGroup *_current_group;
|
||||
|
||||
LVecBase2d _ref_plane_res;
|
||||
// Structures filled when creating a PandaNode directly.
|
||||
PT(PandaNode) _root_node;
|
||||
|
||||
pset<string> _ignored_tags;
|
||||
class VertexEntry {
|
||||
public:
|
||||
VertexEntry();
|
||||
VertexEntry(const ObjToEggConverter *converter, const string &obj_vertex);
|
||||
|
||||
INLINE bool operator < (const VertexEntry &other) const;
|
||||
INLINE bool operator == (const VertexEntry &other) const;
|
||||
INLINE bool matches_except_normal(const VertexEntry &other) const;
|
||||
|
||||
// The 1-based vertex, texcoord, and normal index numbers
|
||||
// appearing in the obj file for this vertex. 0 if the index
|
||||
// number is not given.
|
||||
int _vi, _vti, _vni;
|
||||
|
||||
// The 1-based index number to the synthesized normal, if needed.
|
||||
int _synth_vni;
|
||||
};
|
||||
typedef pmap<VertexEntry, int> UniqueVertexEntries;
|
||||
typedef pvector<VertexEntry> VertexEntries;
|
||||
|
||||
class VertexData {
|
||||
public:
|
||||
VertexData(PandaNode *parent, const string &name);
|
||||
|
||||
int add_vertex(const ObjToEggConverter *converter, const VertexEntry &entry);
|
||||
void add_triangle(int v1, int v2, int v3);
|
||||
void close_geom(const ObjToEggConverter *converter);
|
||||
|
||||
PT(PandaNode) _parent;
|
||||
string _name;
|
||||
PT(GeomNode) _geom_node;
|
||||
|
||||
PT(GeomPrimitive) _prim;
|
||||
VertexEntries _entries;
|
||||
UniqueVertexEntries _unique_entries;
|
||||
|
||||
bool _v4_given, _vt3_given;
|
||||
bool _vt_given, _rgb_given, _vn_given;
|
||||
};
|
||||
|
||||
VertexData *_current_vertex_data;
|
||||
|
||||
friend class VertexData;
|
||||
};
|
||||
|
||||
#include "objToEggConverter.I"
|
||||
|
||||
#endif
|
||||
|
@ -54,6 +54,14 @@ ConfigVariableEnum<DistanceUnit> ptloader_units
|
||||
"when using libptloader to automatically convert files to Panda "
|
||||
"at load time, via e.g. \"pview myMayaFile.mb\"."));
|
||||
|
||||
ConfigVariableBool ptloader_load_node
|
||||
("ptloader-load-node", true,
|
||||
PRC_DESC("Specify true to allow libptloader to invoke the more efficient "
|
||||
"but possibly-experimental code to load model files directly into "
|
||||
"PandaNode when possible. Specify false to force the loading to "
|
||||
"always go through the egg library, which is more likely to be "
|
||||
"reliable."));
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libptloader
|
||||
// Description: Initializes the library. This must be called at
|
||||
|
@ -20,11 +20,13 @@
|
||||
#include "dconfig.h"
|
||||
#include "distanceUnit.h"
|
||||
#include "configVariableEnum.h"
|
||||
#include "configVariableBool.h"
|
||||
|
||||
ConfigureDecl(config_ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
||||
NotifyCategoryDecl(ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
||||
|
||||
extern ConfigVariableEnum<DistanceUnit> ptloader_units;
|
||||
extern ConfigVariableBool ptloader_load_node;
|
||||
|
||||
extern EXPCL_PTLOADER void init_libptloader();
|
||||
|
||||
|
@ -160,8 +160,6 @@ load_file(const Filename &path, const LoaderOptions &options,
|
||||
PT(PandaNode) result;
|
||||
|
||||
SomethingToEggConverter *loader = _loader->make_copy();
|
||||
PT(EggData) egg_data = new EggData;
|
||||
loader->set_egg_data(egg_data);
|
||||
|
||||
DSearchPath file_path;
|
||||
file_path.append_directory(path.get_dirname());
|
||||
@ -185,6 +183,20 @@ load_file(const Filename &path, const LoaderOptions &options,
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to convert directly to PandaNode first, if the converter type
|
||||
// supports it.
|
||||
if (ptloader_load_node && loader->supports_convert_to_node(options)) {
|
||||
result = loader->convert_to_node(options, path);
|
||||
if (!result.is_null()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If the converter type doesn't support the direct PandaNode
|
||||
// conversion, take the slower route through egg instead.
|
||||
PT(EggData) egg_data = new EggData;
|
||||
loader->set_egg_data(egg_data);
|
||||
|
||||
if (loader->convert_file(path)) {
|
||||
DistanceUnit input_units = loader->get_input_units();
|
||||
if (input_units != DU_invalid && ptloader_units != DU_invalid &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user