mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -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 ||
|
nassertv(cdata->_primitive_type == PT_none ||
|
||||||
cdata->_primitive_type == primitive->get_primitive_type());
|
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);
|
CPT(GeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||||
nassertv_always(compat != (GeomPrimitive *)NULL);
|
nassertv_always(compat != (GeomPrimitive *)NULL);
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ add_primitive(const GeomPrimitive *primitive) {
|
|||||||
nassertv(cdata->_primitive_type == PT_none ||
|
nassertv(cdata->_primitive_type == PT_none ||
|
||||||
cdata->_primitive_type == primitive->get_primitive_type());
|
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);
|
CPT(GeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||||
nassertv_always(compat != (GeomPrimitive *)NULL);
|
nassertv_always(compat != (GeomPrimitive *)NULL);
|
||||||
|
|
||||||
@ -591,6 +591,19 @@ rotate_in_place() {
|
|||||||
#endif
|
#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();
|
cdata->_modified = Geom::get_next_modified();
|
||||||
clear_cache_stage(current_thread);
|
clear_cache_stage(current_thread);
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
||||||
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
||||||
triangulator.h triangulator.I \
|
triangulator.h triangulator.I \
|
||||||
|
triangulator3.h triangulator3.I \
|
||||||
unionBoundingVolume.h unionBoundingVolume.I
|
unionBoundingVolume.h unionBoundingVolume.I
|
||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
@ -66,6 +67,7 @@
|
|||||||
stackedPerlinNoise2.cxx \
|
stackedPerlinNoise2.cxx \
|
||||||
stackedPerlinNoise3.cxx \
|
stackedPerlinNoise3.cxx \
|
||||||
triangulator.cxx \
|
triangulator.cxx \
|
||||||
|
triangulator3.cxx \
|
||||||
unionBoundingVolume.cxx
|
unionBoundingVolume.cxx
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
@ -94,6 +96,7 @@
|
|||||||
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
stackedPerlinNoise2.h stackedPerlinNoise2.I \
|
||||||
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
stackedPerlinNoise3.h stackedPerlinNoise3.I \
|
||||||
triangulator.h triangulator.I \
|
triangulator.h triangulator.I \
|
||||||
|
triangulator3.h triangulator3.I \
|
||||||
unionBoundingVolume.h unionBoundingVolume.I
|
unionBoundingVolume.h unionBoundingVolume.I
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
#include "stackedPerlinNoise2.cxx"
|
#include "stackedPerlinNoise2.cxx"
|
||||||
#include "stackedPerlinNoise3.cxx"
|
#include "stackedPerlinNoise3.cxx"
|
||||||
#include "triangulator.cxx"
|
#include "triangulator.cxx"
|
||||||
|
#include "triangulator3.cxx"
|
||||||
|
@ -118,15 +118,28 @@ void Triangulator::
|
|||||||
triangulate() {
|
triangulate() {
|
||||||
_result.clear();
|
_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.
|
// Set up the list of segments.
|
||||||
seg.clear();
|
seg.clear();
|
||||||
seg.push_back(segment_t()); // we don't use the first entry.
|
seg.push_back(segment_t()); // we don't use the first entry.
|
||||||
make_segment(_polygon, true);
|
make_segment(_polygon, true);
|
||||||
|
|
||||||
Holes::const_iterator hi;
|
|
||||||
for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
|
for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
|
||||||
|
if ((*hi).size() >= 3) {
|
||||||
make_segment(*hi, false);
|
make_segment(*hi, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Shuffle the segment index.
|
// Shuffle the segment index.
|
||||||
int num_segments = (int)seg.size() - 1;
|
int num_segments = (int)seg.size() - 1;
|
||||||
@ -151,6 +164,7 @@ triangulate() {
|
|||||||
*/
|
*/
|
||||||
choose_idx = 0;
|
choose_idx = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
//cerr << "got " << num_segments << " segments\n";
|
//cerr << "got " << num_segments << " segments\n";
|
||||||
for (i = 1; i < (int)seg.size(); ++i) {
|
for (i = 1; i < (int)seg.size(); ++i) {
|
||||||
segment_t &s = seg[i];
|
segment_t &s = seg[i];
|
||||||
@ -158,6 +172,7 @@ triangulate() {
|
|||||||
printf(" root0 = %d, root1 = %d\n", s.root0, s.root1);
|
printf(" root0 = %d, root1 = %d\n", s.root0, s.root1);
|
||||||
printf(" next = %d, prev = %d\n", s.next, s.prev);
|
printf(" next = %d, prev = %d\n", s.next, s.prev);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
while (construct_trapezoids(num_segments) != 0) {
|
while (construct_trapezoids(num_segments) != 0) {
|
||||||
// If there's an error, re-shuffle the index and try again.
|
// 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;
|
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 remainder of the code in this file is adapted more or less from
|
||||||
// the C code published with the referenced paper.
|
// the C code published with the referenced paper.
|
||||||
|
@ -31,9 +31,8 @@
|
|||||||
//
|
//
|
||||||
// http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html
|
// http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html
|
||||||
//
|
//
|
||||||
// It works strictly on 2-d points. You'll have to
|
// It works strictly on 2-d points. See Triangulator3
|
||||||
// convert your polygon into a plane if you have 3-d
|
// for 3-d points.
|
||||||
// points.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA_MATHUTIL Triangulator {
|
class EXPCL_PANDA_MATHUTIL Triangulator {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
@ -61,7 +60,9 @@ PUBLISHED:
|
|||||||
int get_triangle_v1(int n) const;
|
int get_triangle_v1(int n) const;
|
||||||
int get_triangle_v2(int n) const;
|
int get_triangle_v2(int n) const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
void cleanup_polygon_indices(vector_int &polygon);
|
||||||
|
|
||||||
typedef pvector<LPoint2d> Vertices;
|
typedef pvector<LPoint2d> Vertices;
|
||||||
Vertices _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
|
// Function: string_to_float
|
||||||
// Description: Another flavor of string_to_float(), this one
|
// Description:
|
||||||
// returns true if the string is a perfectly valid
|
|
||||||
// number (and sets result to that value), or false
|
|
||||||
// otherwise.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool
|
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;
|
string tail;
|
||||||
result = (PN_stdfloat)string_to_double(str, tail);
|
result = (PN_stdfloat)string_to_double(str, tail);
|
||||||
return tail.empty();
|
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 bool string_to_int(const string &str, int &result);
|
||||||
EXPCL_PANDA_PUTIL double string_to_double(const string &str, string &tail);
|
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_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
|
// Convenience function to make a string from anything that has an
|
||||||
// ostream operator.
|
// ostream operator.
|
||||||
|
@ -101,6 +101,22 @@ supports_compressed() const {
|
|||||||
return false;
|
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
|
// Function: SomethingToEggConverter::get_input_units
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -115,6 +131,20 @@ get_input_units() {
|
|||||||
return DU_invalid;
|
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
|
// Function: SomethingToEggConverter::handle_external_reference
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -23,9 +23,11 @@
|
|||||||
#include "pathReplace.h"
|
#include "pathReplace.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "distanceUnit.h"
|
#include "distanceUnit.h"
|
||||||
|
#include "pandaNode.h"
|
||||||
|
|
||||||
class EggData;
|
class EggData;
|
||||||
class EggGroupNode;
|
class EggGroupNode;
|
||||||
|
class LoaderOptions;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : SomethingToEggConverter
|
// Class : SomethingToEggConverter
|
||||||
@ -103,8 +105,10 @@ public:
|
|||||||
virtual string get_extension() const=0;
|
virtual string get_extension() const=0;
|
||||||
virtual string get_additional_extensions() const;
|
virtual string get_additional_extensions() const;
|
||||||
virtual bool supports_compressed() 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 bool convert_file(const Filename &filename)=0;
|
||||||
|
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
|
||||||
virtual DistanceUnit get_input_units();
|
virtual DistanceUnit get_input_units();
|
||||||
|
|
||||||
bool handle_external_reference(EggGroupNode *egg_parent,
|
bool handle_external_reference(EggGroupNode *egg_parent,
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_objegg.cxx config_objegg.h \
|
config_objegg.cxx config_objegg.h \
|
||||||
objToEggConverter.cxx objToEggConverter.h \
|
objToEggConverter.cxx objToEggConverter.h objToEggConverter.I \
|
||||||
eggToObjConverter.cxx eggToObjConverter.h
|
eggToObjConverter.cxx eggToObjConverter.h
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
objToEggConverter.h \
|
objToEggConverter.h objToEggConverter.I \
|
||||||
eggToObjConverter.h
|
eggToObjConverter.h
|
||||||
|
|
||||||
#end ss_lib_target
|
#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 "somethingToEggConverter.h"
|
||||||
#include "eggVertexPool.h"
|
#include "eggVertexPool.h"
|
||||||
#include "eggGroup.h"
|
#include "eggGroup.h"
|
||||||
|
#include "geomVertexData.h"
|
||||||
|
#include "geomVertexWriter.h"
|
||||||
|
#include "geomPrimitive.h"
|
||||||
|
#include "geomNode.h"
|
||||||
|
#include "pandaNode.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : ObjToEggConverter
|
// Class : ObjToEggConverter
|
||||||
@ -36,8 +41,10 @@ public:
|
|||||||
virtual string get_name() const;
|
virtual string get_name() const;
|
||||||
virtual string get_extension() const;
|
virtual string get_extension() const;
|
||||||
virtual bool supports_compressed() const;
|
virtual bool supports_compressed() const;
|
||||||
|
virtual bool supports_convert_to_node(const LoaderOptions &options) const;
|
||||||
|
|
||||||
virtual bool convert_file(const Filename &filename);
|
virtual bool convert_file(const Filename &filename);
|
||||||
|
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool process(const Filename &filename);
|
bool process(const Filename &filename);
|
||||||
@ -47,22 +54,94 @@ protected:
|
|||||||
bool process_v(vector_string &words);
|
bool process_v(vector_string &words);
|
||||||
bool process_vt(vector_string &words);
|
bool process_vt(vector_string &words);
|
||||||
bool process_xvt(vector_string &words);
|
bool process_xvt(vector_string &words);
|
||||||
|
bool process_xvc(vector_string &words);
|
||||||
bool process_vn(vector_string &words);
|
bool process_vn(vector_string &words);
|
||||||
bool process_f(vector_string &words);
|
bool process_f(vector_string &words);
|
||||||
bool process_g(vector_string &words);
|
bool process_g(vector_string &words);
|
||||||
|
|
||||||
EggVertex *get_vertex(int n);
|
|
||||||
EggVertex *get_face_vertex(const string &face_reference);
|
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 _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(EggVertexPool) _vpool;
|
||||||
PT(EggGroup) _root_group;
|
PT(EggGroup) _root_group;
|
||||||
EggGroup *_current_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
|
#endif
|
||||||
|
@ -54,6 +54,14 @@ ConfigVariableEnum<DistanceUnit> ptloader_units
|
|||||||
"when using libptloader to automatically convert files to Panda "
|
"when using libptloader to automatically convert files to Panda "
|
||||||
"at load time, via e.g. \"pview myMayaFile.mb\"."));
|
"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
|
// Function: init_libptloader
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -20,11 +20,13 @@
|
|||||||
#include "dconfig.h"
|
#include "dconfig.h"
|
||||||
#include "distanceUnit.h"
|
#include "distanceUnit.h"
|
||||||
#include "configVariableEnum.h"
|
#include "configVariableEnum.h"
|
||||||
|
#include "configVariableBool.h"
|
||||||
|
|
||||||
ConfigureDecl(config_ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
ConfigureDecl(config_ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
||||||
NotifyCategoryDecl(ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
NotifyCategoryDecl(ptloader, EXPCL_PTLOADER, EXPTP_PTLOADER);
|
||||||
|
|
||||||
extern ConfigVariableEnum<DistanceUnit> ptloader_units;
|
extern ConfigVariableEnum<DistanceUnit> ptloader_units;
|
||||||
|
extern ConfigVariableBool ptloader_load_node;
|
||||||
|
|
||||||
extern EXPCL_PTLOADER void init_libptloader();
|
extern EXPCL_PTLOADER void init_libptloader();
|
||||||
|
|
||||||
|
@ -160,8 +160,6 @@ load_file(const Filename &path, const LoaderOptions &options,
|
|||||||
PT(PandaNode) result;
|
PT(PandaNode) result;
|
||||||
|
|
||||||
SomethingToEggConverter *loader = _loader->make_copy();
|
SomethingToEggConverter *loader = _loader->make_copy();
|
||||||
PT(EggData) egg_data = new EggData;
|
|
||||||
loader->set_egg_data(egg_data);
|
|
||||||
|
|
||||||
DSearchPath file_path;
|
DSearchPath file_path;
|
||||||
file_path.append_directory(path.get_dirname());
|
file_path.append_directory(path.get_dirname());
|
||||||
@ -185,6 +183,20 @@ load_file(const Filename &path, const LoaderOptions &options,
|
|||||||
break;
|
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)) {
|
if (loader->convert_file(path)) {
|
||||||
DistanceUnit input_units = loader->get_input_units();
|
DistanceUnit input_units = loader->get_input_units();
|
||||||
if (input_units != DU_invalid && ptloader_units != DU_invalid &&
|
if (input_units != DU_invalid && ptloader_units != DU_invalid &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user