mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
compute and load tangent and binormal
This commit is contained in:
parent
fa2e6eb726
commit
5d83609638
@ -17,3 +17,24 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggGroupNode::TBNVertexValue::operator <
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool EggGroupNode::TBNVertexValue::
|
||||||
|
operator < (const TBNVertexValue &other) const {
|
||||||
|
int compare = _pos.compare_to(other._pos);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare < 0;
|
||||||
|
}
|
||||||
|
compare = _normal.compare_to(other._normal);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare < 0;
|
||||||
|
}
|
||||||
|
compare = _uv.compare_to(other._uv);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare < 0;
|
||||||
|
}
|
||||||
|
return _uv_name < other._uv_name;
|
||||||
|
}
|
||||||
|
@ -695,6 +695,45 @@ strip_normals() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggGroupNode::recompute_tangent_binormal
|
||||||
|
// Access: Published
|
||||||
|
// Description: This function recomputes the tangent and binormal for
|
||||||
|
// the named texture coordinate set for all vertices at
|
||||||
|
// this level and below. Use the empty string for the
|
||||||
|
// default texture coordinate set.
|
||||||
|
//
|
||||||
|
// It is necessary for each vertex to already have a
|
||||||
|
// normal (or at least a polygon normal), as well as a
|
||||||
|
// texture coordinate in the named texture coordinate
|
||||||
|
// set, before calling this function. You might precede
|
||||||
|
// this with recompute_vertex_normals() to ensure that
|
||||||
|
// the normals exist.
|
||||||
|
//
|
||||||
|
// Like recompute_vertex_normals(), this function does
|
||||||
|
// not remove or adjust vertices in the vertex pool; it
|
||||||
|
// only adds new vertices with the normals removed.
|
||||||
|
// Thus, it is a good idea to call
|
||||||
|
// remove_unused_vertices() after calling this.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggGroupNode::
|
||||||
|
recompute_tangent_binormal(const GlobPattern &uv_name) {
|
||||||
|
// First, collect all the vertices together with their shared
|
||||||
|
// polygons.
|
||||||
|
TBNVertexCollection collection;
|
||||||
|
r_collect_tangent_binormal(uv_name, collection);
|
||||||
|
|
||||||
|
// Now compute the tangent and binormal separately for each common
|
||||||
|
// group of vertices.
|
||||||
|
TBNVertexCollection::const_iterator ci;
|
||||||
|
for (ci = collection.begin(); ci != collection.end(); ++ci) {
|
||||||
|
const TBNVertexValue &value = (*ci).first;
|
||||||
|
const TBNVertexGroup &group = (*ci).second;
|
||||||
|
|
||||||
|
do_compute_tangent_binormal(value, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggGroupNode::triangulate_polygons
|
// Function: EggGroupNode::triangulate_polygons
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -1644,7 +1683,7 @@ r_collect_vertex_normals(EggGroupNode::NVertexCollection &collection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggGroupNode::r_collect_vertex_normals
|
// Function: EggGroupNode::do_compute_vertex_normals
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: This is part of the implementation of
|
// Description: This is part of the implementation of
|
||||||
// recompute_vertex_normals(). It accepts a group of
|
// recompute_vertex_normals(). It accepts a group of
|
||||||
@ -1683,3 +1722,159 @@ do_compute_vertex_normals(const NVertexGroup &group) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggGroupNode::r_collect_tangent_binormal
|
||||||
|
// Access: Private
|
||||||
|
// Description: This is part of the implementation of
|
||||||
|
// recompute_tangent_binormal(). It walks the scene
|
||||||
|
// graph at this group node and below, identifying all
|
||||||
|
// the polygons and the vertices they have in common.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggGroupNode::
|
||||||
|
r_collect_tangent_binormal(const GlobPattern &uv_name,
|
||||||
|
EggGroupNode::TBNVertexCollection &collection) {
|
||||||
|
Children::iterator ci;
|
||||||
|
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||||
|
EggNode *child = *ci;
|
||||||
|
|
||||||
|
if (child->is_of_type(EggPolygon::get_class_type())) {
|
||||||
|
EggPolygon *polygon = DCAST(EggPolygon, child);
|
||||||
|
|
||||||
|
TBNVertexReference ref;
|
||||||
|
ref._polygon = polygon;
|
||||||
|
|
||||||
|
// Now add each vertex from the polygon separately to our
|
||||||
|
// collection.
|
||||||
|
size_t num_vertices = polygon->size();
|
||||||
|
for (size_t i = 0; i < num_vertices; i++) {
|
||||||
|
// We look at the triangle formed by each three consecutive
|
||||||
|
// vertices to determine the s direction and t direction at
|
||||||
|
// each vertex. v1 is the key vertex, the one at position i;
|
||||||
|
// v2 is vertex i + 1, and v3 is vertex i - 1.
|
||||||
|
EggVertex *v1 = polygon->get_vertex(i);
|
||||||
|
EggVertex *v2 = polygon->get_vertex((i + 1) % num_vertices);
|
||||||
|
EggVertex *v3 = polygon->get_vertex((i + num_vertices - 1) % num_vertices);
|
||||||
|
if (v1->has_normal() || polygon->has_normal()) {
|
||||||
|
// Go through all of the UV names on the vertex, looking for
|
||||||
|
// one that matches the glob pattern.
|
||||||
|
EggVertex::const_uv_iterator uvi;
|
||||||
|
for (uvi = v1->uv_begin(); uvi != v1->uv_end(); ++uvi) {
|
||||||
|
EggVertexUV *uv_obj = (*uvi);
|
||||||
|
string name = uv_obj->get_name();
|
||||||
|
if (uv_name.matches(name) &&
|
||||||
|
v2->has_uv(name) && v3->has_uv(name)) {
|
||||||
|
TBNVertexValue value;
|
||||||
|
value._uv_name = name;
|
||||||
|
value._pos = v1->get_pos3();
|
||||||
|
if (v1->has_normal()) {
|
||||||
|
value._normal = v1->get_normal();
|
||||||
|
} else {
|
||||||
|
value._normal = polygon->get_normal();
|
||||||
|
}
|
||||||
|
value._uv = v1->get_uv(name);
|
||||||
|
|
||||||
|
// Compute the s direction and t direction for this vertex.
|
||||||
|
LPoint3d p1 = v1->get_pos3();
|
||||||
|
LPoint3d p2 = v2->get_pos3();
|
||||||
|
LPoint3d p3 = v3->get_pos3();
|
||||||
|
|
||||||
|
TexCoordd w1 = v1->get_uv(name);
|
||||||
|
TexCoordd w2 = v2->get_uv(name);
|
||||||
|
TexCoordd w3 = v3->get_uv(name);
|
||||||
|
|
||||||
|
double x1 = p2[0] - p1[0];
|
||||||
|
double x2 = p3[0] - p1[0];
|
||||||
|
double y1 = p2[1] - p1[1];
|
||||||
|
double y2 = p3[1] - p1[1];
|
||||||
|
double z1 = p2[2] - p1[2];
|
||||||
|
double z2 = p3[2] - p1[2];
|
||||||
|
|
||||||
|
double s1 = w2[0] - w1[0];
|
||||||
|
double s2 = w3[0] - w1[0];
|
||||||
|
double t1 = w2[1] - w1[1];
|
||||||
|
double t2 = w3[1] - w1[1];
|
||||||
|
|
||||||
|
double r = 1.0f / (s1 * t2 - s2 * t1);
|
||||||
|
ref._sdir.set((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||||
|
(t2 * z1 - t1 * z2) * r);
|
||||||
|
ref._tdir.set((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||||
|
(s1 * z2 - s2 * z1) * r);
|
||||||
|
|
||||||
|
// Store the vertex referenced to the polygon.
|
||||||
|
ref._vertex = i;
|
||||||
|
collection[value].push_back(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||||
|
EggGroupNode *group = DCAST(EggGroupNode, child);
|
||||||
|
|
||||||
|
// We can't share vertices across an Instance node. Don't
|
||||||
|
// even bother trying. Instead, just restart.
|
||||||
|
if (group->is_under_instance()) {
|
||||||
|
group->recompute_tangent_binormal(uv_name);
|
||||||
|
} else {
|
||||||
|
group->r_collect_tangent_binormal(uv_name, collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggGroupNode::do_compute_tangent_binormal
|
||||||
|
// Access: Private
|
||||||
|
// Description: This is part of the implementation of
|
||||||
|
// recompute_tangent_binormal(). It accepts a group of
|
||||||
|
// polygons and their common normals and UV's, and
|
||||||
|
// computes the tangent and binormal for all their
|
||||||
|
// shared vertices.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggGroupNode::
|
||||||
|
do_compute_tangent_binormal(const TBNVertexValue &value,
|
||||||
|
const TBNVertexGroup &group) {
|
||||||
|
nassertv(!group.empty());
|
||||||
|
|
||||||
|
// Accumulate together all of the s vectors and t vectors computed
|
||||||
|
// for the different vertices that are together here.
|
||||||
|
Normald sdir(0.0, 0.0, 0.0);
|
||||||
|
Normald tdir(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
TBNVertexGroup::const_iterator gi;
|
||||||
|
for (gi = group.begin(); gi != group.end(); ++gi) {
|
||||||
|
const TBNVertexReference &ref = (*gi);
|
||||||
|
sdir += ref._sdir;
|
||||||
|
tdir += ref._tdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
Normald tangent = (sdir - value._normal * value._normal.dot(sdir));
|
||||||
|
tangent.normalize();
|
||||||
|
|
||||||
|
Normald binormal = cross(value._normal, tangent);
|
||||||
|
if (dot(binormal, tdir) < 0.0f) {
|
||||||
|
binormal = -binormal;
|
||||||
|
}
|
||||||
|
// Shouldn't need to normalize this, but we do just for good measure.
|
||||||
|
binormal.normalize();
|
||||||
|
|
||||||
|
// Now we have the common tangent and binormal; apply them to all
|
||||||
|
// the vertices.
|
||||||
|
|
||||||
|
for (gi = group.begin(); gi != group.end(); ++gi) {
|
||||||
|
const TBNVertexReference &ref = (*gi);
|
||||||
|
EggVertex *vertex = ref._polygon->get_vertex(ref._vertex);
|
||||||
|
EggVertexPool *pool = vertex->get_pool();
|
||||||
|
|
||||||
|
EggVertex new_vertex(*vertex);
|
||||||
|
EggVertexUV *uv_obj = new_vertex.get_uv_obj(value._uv_name);
|
||||||
|
nassertv(uv_obj != (EggVertexUV *)NULL);
|
||||||
|
uv_obj->set_tangent(tangent);
|
||||||
|
uv_obj->set_binormal(binormal);
|
||||||
|
|
||||||
|
EggVertex *unique = pool->create_unique_vertex(new_vertex);
|
||||||
|
unique->copy_grefs_from(*vertex);
|
||||||
|
|
||||||
|
ref._polygon->set_vertex(ref._vertex, unique);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "typedObject.h"
|
#include "typedObject.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
|
#include "globPattern.h"
|
||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
|
|
||||||
class EggTextureCollection;
|
class EggTextureCollection;
|
||||||
@ -130,6 +130,8 @@ PUBLISHED:
|
|||||||
void recompute_polygon_normals(CoordinateSystem cs = CS_default);
|
void recompute_polygon_normals(CoordinateSystem cs = CS_default);
|
||||||
void strip_normals();
|
void strip_normals();
|
||||||
|
|
||||||
|
void recompute_tangent_binormal(const GlobPattern &uv_name);
|
||||||
|
|
||||||
enum TriangulateFlags {
|
enum TriangulateFlags {
|
||||||
T_polygon = 0x001,
|
T_polygon = 0x001,
|
||||||
T_convex = 0x002,
|
T_convex = 0x002,
|
||||||
@ -197,6 +199,30 @@ private:
|
|||||||
double threshold, CoordinateSystem cs);
|
double threshold, CoordinateSystem cs);
|
||||||
void do_compute_vertex_normals(const NVertexGroup &group);
|
void do_compute_vertex_normals(const NVertexGroup &group);
|
||||||
|
|
||||||
|
// This bit is in support of recompute_tangent_binormal().
|
||||||
|
class TBNVertexReference {
|
||||||
|
public:
|
||||||
|
EggPolygon *_polygon;
|
||||||
|
size_t _vertex;
|
||||||
|
LVector3d _sdir;
|
||||||
|
LVector3d _tdir;
|
||||||
|
};
|
||||||
|
class TBNVertexValue {
|
||||||
|
public:
|
||||||
|
INLINE bool operator < (const TBNVertexValue &other) const;
|
||||||
|
Vertexd _pos;
|
||||||
|
Normald _normal;
|
||||||
|
string _uv_name;
|
||||||
|
TexCoordd _uv;
|
||||||
|
};
|
||||||
|
typedef pvector<TBNVertexReference> TBNVertexGroup;
|
||||||
|
typedef pmap<TBNVertexValue, TBNVertexGroup> TBNVertexCollection;
|
||||||
|
|
||||||
|
void r_collect_tangent_binormal(const GlobPattern &uv_name,
|
||||||
|
TBNVertexCollection &collection);
|
||||||
|
void do_compute_tangent_binormal(const TBNVertexValue &value,
|
||||||
|
const TBNVertexGroup &group);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
return _type_handle;
|
return _type_handle;
|
||||||
|
@ -412,6 +412,11 @@ transform(const LMatrix4d &mat) {
|
|||||||
morph.set_offset((*mi).get_offset() * mat);
|
morph.set_offset((*mi).get_offset() * mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UVMap::iterator ui;
|
||||||
|
for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) {
|
||||||
|
(*ui).second->transform(mat);
|
||||||
|
}
|
||||||
|
|
||||||
EggAttributes::transform(mat);
|
EggAttributes::transform(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,26 +295,34 @@ has_uvs() const {
|
|||||||
// Function: EggVertexPool::get_uv_names
|
// Function: EggVertexPool::get_uv_names
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Returns the list of UV names that are defined by any
|
// Description: Returns the list of UV names that are defined by any
|
||||||
// vertices in the pool. It is the user's
|
// vertices in the pool. Also returns the subset of UV
|
||||||
// responsibility to clear the vector before calling
|
// names that define the tangent and binormal. It is
|
||||||
// this method.
|
// the user's responsibility to clear both vectors
|
||||||
|
// before calling this method.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void EggVertexPool::
|
void EggVertexPool::
|
||||||
get_uv_names(vector_string &uv_names) const {
|
get_uv_names(vector_string &uv_names, vector_string &tbn_names) const {
|
||||||
pset<string> names;
|
pset<string> uv_names_set, tbn_names_set;
|
||||||
IndexVertices::const_iterator ivi;
|
IndexVertices::const_iterator ivi;
|
||||||
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
|
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
|
||||||
EggVertex *vertex = (*ivi).second;
|
EggVertex *vertex = (*ivi).second;
|
||||||
EggVertex::const_uv_iterator uvi;
|
EggVertex::const_uv_iterator uvi;
|
||||||
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
|
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
|
||||||
names.insert((*uvi)->get_name());
|
EggVertexUV *uv_obj = (*uvi);
|
||||||
|
uv_names_set.insert(uv_obj->get_name());
|
||||||
|
if (uv_obj->has_tangent() && uv_obj->has_binormal()) {
|
||||||
|
tbn_names_set.insert(uv_obj->get_name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pset<string>::const_iterator si;
|
pset<string>::const_iterator si;
|
||||||
for (si = names.begin(); si != names.end(); ++si) {
|
for (si = uv_names_set.begin(); si != uv_names_set.end(); ++si) {
|
||||||
uv_names.push_back(*si);
|
uv_names.push_back(*si);
|
||||||
}
|
}
|
||||||
|
for (si = tbn_names_set.begin(); si != tbn_names_set.end(); ++si) {
|
||||||
|
tbn_names.push_back(*si);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -98,7 +98,7 @@ PUBLISHED:
|
|||||||
bool has_colors() const;
|
bool has_colors() const;
|
||||||
bool has_nonwhite_colors() const;
|
bool has_nonwhite_colors() const;
|
||||||
bool has_uvs() const;
|
bool has_uvs() const;
|
||||||
void get_uv_names(vector_string &uv_names) const;
|
void get_uv_names(vector_string &uv_names, vector_string &tbn_names) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Can be used to traverse all the vertices in index number order.
|
// Can be used to traverse all the vertices in index number order.
|
||||||
|
@ -36,3 +36,87 @@ INLINE void EggVertexUV::
|
|||||||
set_uv(const TexCoordd &uv) {
|
set_uv(const TexCoordd &uv) {
|
||||||
_uv = uv;
|
_uv = uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::has_tangent
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool EggVertexUV::
|
||||||
|
has_tangent() const {
|
||||||
|
return (_flags & F_has_tangent) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::get_tangent
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Normald &EggVertexUV::
|
||||||
|
get_tangent() const {
|
||||||
|
nassertr(has_tangent(), _tangent);
|
||||||
|
return _tangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::set_tangent
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void EggVertexUV::
|
||||||
|
set_tangent(const Normald &tangent) {
|
||||||
|
_tangent = tangent;
|
||||||
|
_flags |= F_has_tangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::clear_tangent
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void EggVertexUV::
|
||||||
|
clear_tangent() {
|
||||||
|
_flags &= ~F_has_tangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::has_binormal
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool EggVertexUV::
|
||||||
|
has_binormal() const {
|
||||||
|
return (_flags & F_has_binormal) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::get_binormal
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Normald &EggVertexUV::
|
||||||
|
get_binormal() const {
|
||||||
|
nassertr(has_binormal(), _binormal);
|
||||||
|
return _binormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::set_binormal
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void EggVertexUV::
|
||||||
|
set_binormal(const Normald &binormal) {
|
||||||
|
_binormal = binormal;
|
||||||
|
_flags |= F_has_binormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::clear_binormal
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void EggVertexUV::
|
||||||
|
clear_binormal() {
|
||||||
|
_flags &= ~F_has_binormal;
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ TypeHandle EggVertexUV::_type_handle;
|
|||||||
EggVertexUV::
|
EggVertexUV::
|
||||||
EggVertexUV(const string &name, const TexCoordd &uv) :
|
EggVertexUV(const string &name, const TexCoordd &uv) :
|
||||||
EggNamedObject(name),
|
EggNamedObject(name),
|
||||||
|
_flags(0),
|
||||||
_uv(uv)
|
_uv(uv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -44,6 +45,9 @@ EggVertexUV::
|
|||||||
EggVertexUV(const EggVertexUV ©) :
|
EggVertexUV(const EggVertexUV ©) :
|
||||||
EggNamedObject(copy),
|
EggNamedObject(copy),
|
||||||
_duvs(copy._duvs),
|
_duvs(copy._duvs),
|
||||||
|
_flags(copy._flags),
|
||||||
|
_tangent(copy._tangent),
|
||||||
|
_binormal(copy._binormal),
|
||||||
_uv(copy._uv)
|
_uv(copy._uv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -57,6 +61,9 @@ EggVertexUV &EggVertexUV::
|
|||||||
operator = (const EggVertexUV ©) {
|
operator = (const EggVertexUV ©) {
|
||||||
EggNamedObject::operator = (copy);
|
EggNamedObject::operator = (copy);
|
||||||
_duvs = copy._duvs;
|
_duvs = copy._duvs;
|
||||||
|
_flags = copy._flags;
|
||||||
|
_tangent = copy._tangent;
|
||||||
|
_binormal = copy._binormal;
|
||||||
_uv = copy._uv;
|
_uv = copy._uv;
|
||||||
|
|
||||||
return (*this);
|
return (*this);
|
||||||
@ -71,6 +78,25 @@ EggVertexUV::
|
|||||||
~EggVertexUV() {
|
~EggVertexUV() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggVertexUV::transform
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Applies the indicated transformation matrix to the
|
||||||
|
// UV's tangent and/or binormal. This does nothing if
|
||||||
|
// there is no tangent or binormal.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggVertexUV::
|
||||||
|
transform(const LMatrix4d &mat) {
|
||||||
|
if (has_tangent()) {
|
||||||
|
_tangent = _tangent * mat;
|
||||||
|
_tangent.normalize();
|
||||||
|
}
|
||||||
|
if (has_binormal()) {
|
||||||
|
_binormal = _binormal * mat;
|
||||||
|
_binormal.normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggVertexUV::write
|
// Function: EggVertexUV::write
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -83,12 +109,20 @@ write(ostream &out, int indent_level) const {
|
|||||||
inline_name += ' ';
|
inline_name += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_duvs.empty()) {
|
if (_duvs.empty() && _flags == 0) {
|
||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "<UV> " << inline_name << "{ " << get_uv() << " }\n";
|
<< "<UV> " << inline_name << "{ " << get_uv() << " }\n";
|
||||||
} else {
|
} else {
|
||||||
indent(out, indent_level) << "<UV> " << inline_name << "{\n";
|
indent(out, indent_level) << "<UV> " << inline_name << "{\n";
|
||||||
indent(out, indent_level+2) << get_uv() << "\n";
|
indent(out, indent_level+2) << get_uv() << "\n";
|
||||||
|
if (has_tangent()) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "<Tangent> { " << get_tangent() << " }\n";
|
||||||
|
}
|
||||||
|
if (has_binormal()) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "<Binormal> { " << get_binormal() << " }\n";
|
||||||
|
}
|
||||||
_duvs.write(out, indent_level+2);
|
_duvs.write(out, indent_level+2);
|
||||||
indent(out, indent_level) << "}\n";
|
indent(out, indent_level) << "}\n";
|
||||||
}
|
}
|
||||||
@ -103,11 +137,29 @@ write(ostream &out, int indent_level) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int EggVertexUV::
|
int EggVertexUV::
|
||||||
compare_to(const EggVertexUV &other) const {
|
compare_to(const EggVertexUV &other) const {
|
||||||
int compare =
|
if (_flags != other._flags) {
|
||||||
_uv.compare_to(other._uv, egg_parameters->_uv_threshold);
|
return _flags - other._flags;
|
||||||
|
}
|
||||||
|
int compare;
|
||||||
|
compare = _uv.compare_to(other._uv, egg_parameters->_uv_threshold);
|
||||||
if (compare != 0) {
|
if (compare != 0) {
|
||||||
return compare;
|
return compare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_tangent()) {
|
||||||
|
compare = _tangent.compare_to(other._tangent, egg_parameters->_normal_threshold);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_binormal()) {
|
||||||
|
compare = _binormal.compare_to(other._binormal, egg_parameters->_normal_threshold);
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_duvs != other._duvs) {
|
if (_duvs != other._duvs) {
|
||||||
return _duvs < other._duvs ? -1 : 1;
|
return _duvs < other._duvs ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,32 @@ PUBLISHED:
|
|||||||
INLINE const TexCoordd &get_uv() const;
|
INLINE const TexCoordd &get_uv() const;
|
||||||
INLINE void set_uv(const TexCoordd &texCoord);
|
INLINE void set_uv(const TexCoordd &texCoord);
|
||||||
|
|
||||||
|
INLINE bool has_tangent() const;
|
||||||
|
INLINE const Normald &get_tangent() const;
|
||||||
|
INLINE void set_tangent(const Normald &tangent);
|
||||||
|
INLINE void clear_tangent();
|
||||||
|
|
||||||
|
INLINE bool has_binormal() const;
|
||||||
|
INLINE const Normald &get_binormal() const;
|
||||||
|
INLINE void set_binormal(const Normald &binormal);
|
||||||
|
INLINE void clear_binormal();
|
||||||
|
|
||||||
|
void transform(const LMatrix4d &mat);
|
||||||
|
|
||||||
void write(ostream &out, int indent_level) const;
|
void write(ostream &out, int indent_level) const;
|
||||||
int compare_to(const EggVertexUV &other) const;
|
int compare_to(const EggVertexUV &other) const;
|
||||||
|
|
||||||
EggMorphTexCoordList _duvs;
|
EggMorphTexCoordList _duvs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum Flags {
|
||||||
|
F_has_tangent = 0x001,
|
||||||
|
F_has_binormal = 0x002,
|
||||||
|
};
|
||||||
|
|
||||||
|
int _flags;
|
||||||
|
Normald _tangent;
|
||||||
|
Normald _binormal;
|
||||||
TexCoordd _uv;
|
TexCoordd _uv;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -351,6 +351,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
accept();
|
accept();
|
||||||
return BILLBOARDCENTER;
|
return BILLBOARDCENTER;
|
||||||
}
|
}
|
||||||
|
"<BINORMAL>" {
|
||||||
|
accept();
|
||||||
|
return BINORMAL;
|
||||||
|
}
|
||||||
"<BUNDLE>" {
|
"<BUNDLE>" {
|
||||||
accept();
|
accept();
|
||||||
return BUNDLE;
|
return BUNDLE;
|
||||||
@ -579,6 +583,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
accept();
|
accept();
|
||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
"<TANGENT>" {
|
||||||
|
accept();
|
||||||
|
return TANGENT;
|
||||||
|
}
|
||||||
"<TEXLIST>" {
|
"<TEXLIST>" {
|
||||||
accept();
|
accept();
|
||||||
return TEXLIST;
|
return TEXLIST;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,85 +8,87 @@
|
|||||||
# define BFACE 261
|
# define BFACE 261
|
||||||
# define BILLBOARD 262
|
# define BILLBOARD 262
|
||||||
# define BILLBOARDCENTER 263
|
# define BILLBOARDCENTER 263
|
||||||
# define BUNDLE 264
|
# define BINORMAL 264
|
||||||
# define CLOSED 265
|
# define BUNDLE 265
|
||||||
# define COLLIDE 266
|
# define CLOSED 266
|
||||||
# define COMMENT 267
|
# define COLLIDE 267
|
||||||
# define COMPONENT 268
|
# define COMMENT 268
|
||||||
# define COORDSYSTEM 269
|
# define COMPONENT 269
|
||||||
# define CV 270
|
# define COORDSYSTEM 270
|
||||||
# define DART 271
|
# define CV 271
|
||||||
# define DNORMAL 272
|
# define DART 272
|
||||||
# define DRGBA 273
|
# define DNORMAL 273
|
||||||
# define DUV 274
|
# define DRGBA 274
|
||||||
# define DXYZ 275
|
# define DUV 275
|
||||||
# define DCS 276
|
# define DXYZ 276
|
||||||
# define DISTANCE 277
|
# define DCS 277
|
||||||
# define DTREF 278
|
# define DISTANCE 278
|
||||||
# define DYNAMICVERTEXPOOL 279
|
# define DTREF 279
|
||||||
# define EXTERNAL_FILE 280
|
# define DYNAMICVERTEXPOOL 280
|
||||||
# define FLIGHT 281
|
# define EXTERNAL_FILE 281
|
||||||
# define GROUP 282
|
# define FLIGHT 282
|
||||||
# define HIP 283
|
# define GROUP 283
|
||||||
# define INTANGENT 284
|
# define HIP 284
|
||||||
# define JOINT 285
|
# define INTANGENT 285
|
||||||
# define KNOTS 286
|
# define JOINT 286
|
||||||
# define INCLUDE 287
|
# define KNOTS 287
|
||||||
# define INSTANCE 288
|
# define INCLUDE 288
|
||||||
# define LINE 289
|
# define INSTANCE 289
|
||||||
# define LOOP 290
|
# define LINE 290
|
||||||
# define MATERIAL 291
|
# define LOOP 291
|
||||||
# define MATRIX3 292
|
# define MATERIAL 292
|
||||||
# define MATRIX4 293
|
# define MATRIX3 293
|
||||||
# define MODEL 294
|
# define MATRIX4 294
|
||||||
# define MREF 295
|
# define MODEL 295
|
||||||
# define NORMAL 296
|
# define MREF 296
|
||||||
# define NURBSCURVE 297
|
# define NORMAL 297
|
||||||
# define NURBSSURFACE 298
|
# define NURBSCURVE 298
|
||||||
# define OBJECTTYPE 299
|
# define NURBSSURFACE 299
|
||||||
# define ORDER 300
|
# define OBJECTTYPE 300
|
||||||
# define OUTTANGENT 301
|
# define ORDER 301
|
||||||
# define POINTLIGHT 302
|
# define OUTTANGENT 302
|
||||||
# define POLYGON 303
|
# define POINTLIGHT 303
|
||||||
# define REF 304
|
# define POLYGON 304
|
||||||
# define RGBA 305
|
# define REF 305
|
||||||
# define ROTATE 306
|
# define RGBA 306
|
||||||
# define ROTX 307
|
# define ROTATE 307
|
||||||
# define ROTY 308
|
# define ROTX 308
|
||||||
# define ROTZ 309
|
# define ROTY 309
|
||||||
# define SANIM 310
|
# define ROTZ 310
|
||||||
# define SCALAR 311
|
# define SANIM 311
|
||||||
# define SCALE 312
|
# define SCALAR 312
|
||||||
# define SEQUENCE 313
|
# define SCALE 313
|
||||||
# define SHADING 314
|
# define SEQUENCE 314
|
||||||
# define SWITCH 315
|
# define SHADING 315
|
||||||
# define SWITCHCONDITION 316
|
# define SWITCH 316
|
||||||
# define TABLE 317
|
# define SWITCHCONDITION 317
|
||||||
# define TABLE_V 318
|
# define TABLE 318
|
||||||
# define TAG 319
|
# define TABLE_V 319
|
||||||
# define TEXLIST 320
|
# define TAG 320
|
||||||
# define TEXTURE 321
|
# define TANGENT 321
|
||||||
# define TLENGTHS 322
|
# define TEXLIST 322
|
||||||
# define TRANSFORM 323
|
# define TEXTURE 323
|
||||||
# define TRANSLATE 324
|
# define TLENGTHS 324
|
||||||
# define TREF 325
|
# define TRANSFORM 325
|
||||||
# define TRIANGLEFAN 326
|
# define TRANSLATE 326
|
||||||
# define TRIANGLESTRIP 327
|
# define TREF 327
|
||||||
# define TRIM 328
|
# define TRIANGLEFAN 328
|
||||||
# define TXT 329
|
# define TRIANGLESTRIP 329
|
||||||
# define UKNOTS 330
|
# define TRIM 330
|
||||||
# define UV 331
|
# define TXT 331
|
||||||
# define VKNOTS 332
|
# define UKNOTS 332
|
||||||
# define VERTEX 333
|
# define UV 333
|
||||||
# define VERTEXANIM 334
|
# define VKNOTS 334
|
||||||
# define VERTEXPOOL 335
|
# define VERTEX 335
|
||||||
# define VERTEXREF 336
|
# define VERTEXANIM 336
|
||||||
# define XFMANIM 337
|
# define VERTEXPOOL 337
|
||||||
# define XFMSANIM 338
|
# define VERTEXREF 338
|
||||||
# define START_EGG 339
|
# define XFMANIM 339
|
||||||
# define START_GROUP_BODY 340
|
# define XFMSANIM 340
|
||||||
# define START_TEXTURE_BODY 341
|
# define START_EGG 341
|
||||||
# define START_PRIMITIVE_BODY 342
|
# define START_GROUP_BODY 342
|
||||||
|
# define START_TEXTURE_BODY 343
|
||||||
|
# define START_PRIMITIVE_BODY 344
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE eggyylval;
|
extern YYSTYPE eggyylval;
|
||||||
|
@ -146,7 +146,7 @@ egg_cleanup_parser() {
|
|||||||
%token <_ulong> ULONG
|
%token <_ulong> ULONG
|
||||||
%token <_string> STRING
|
%token <_string> STRING
|
||||||
|
|
||||||
%token BEZIERCURVE BFACE BILLBOARD BILLBOARDCENTER BUNDLE CLOSED
|
%token BEZIERCURVE BFACE BILLBOARD BILLBOARDCENTER BINORMAL BUNDLE CLOSED
|
||||||
%token COLLIDE COMMENT COMPONENT
|
%token COLLIDE COMMENT COMPONENT
|
||||||
%token COORDSYSTEM CV DART
|
%token COORDSYSTEM CV DART
|
||||||
%token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
|
%token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
|
||||||
@ -157,7 +157,7 @@ egg_cleanup_parser() {
|
|||||||
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
|
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
|
||||||
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
|
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
|
||||||
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
|
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
|
||||||
%token TABLE TABLE_V TAG TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
|
%token TABLE TABLE_V TAG TANGENT TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
|
||||||
%token TREF TRIANGLEFAN TRIANGLESTRIP
|
%token TREF TRIANGLEFAN TRIANGLESTRIP
|
||||||
%token TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
|
%token TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
|
||||||
%token VERTEXPOOL VERTEXREF
|
%token VERTEXPOOL VERTEXREF
|
||||||
@ -952,6 +952,22 @@ vertex_uv_body:
|
|||||||
real real
|
real real
|
||||||
{
|
{
|
||||||
DCAST(EggVertexUV, egg_stack.back())->set_uv(TexCoordd($1, $2));
|
DCAST(EggVertexUV, egg_stack.back())->set_uv(TexCoordd($1, $2));
|
||||||
|
}
|
||||||
|
| vertex_uv_body TANGENT '{' real real real '}'
|
||||||
|
{
|
||||||
|
if (DCAST(EggVertexUV, egg_stack.back())->has_tangent()) {
|
||||||
|
eggyywarning("Ignoring repeated tangent");
|
||||||
|
} else {
|
||||||
|
DCAST(EggVertexUV, egg_stack.back())->set_tangent(Normald($4, $5, $6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| vertex_uv_body BINORMAL '{' real real real '}'
|
||||||
|
{
|
||||||
|
if (DCAST(EggVertexUV, egg_stack.back())->has_binormal()) {
|
||||||
|
eggyywarning("Ignoring repeated binormal");
|
||||||
|
} else {
|
||||||
|
DCAST(EggVertexUV, egg_stack.back())->set_binormal(Normald($4, $5, $6));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| vertex_uv_body DUV string '{' real real '}'
|
| vertex_uv_body DUV string '{' real real '}'
|
||||||
{
|
{
|
||||||
|
@ -371,21 +371,85 @@ make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform,
|
|||||||
// Now, is our parent node a GeomNode, or just an ordinary
|
// Now, is our parent node a GeomNode, or just an ordinary
|
||||||
// PandaNode? If it's a GeomNode, we can add the new Geom directly
|
// PandaNode? If it's a GeomNode, we can add the new Geom directly
|
||||||
// to our parent; otherwise, we need to create a new node.
|
// to our parent; otherwise, we need to create a new node.
|
||||||
|
PT(GeomNode) geom_node;
|
||||||
if (parent->is_geom_node() && !render_state->_hidden) {
|
if (parent->is_geom_node() && !render_state->_hidden) {
|
||||||
DCAST(GeomNode, parent)->add_geom(geom, render_state->_state);
|
geom_node = DCAST(GeomNode, parent);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PT(GeomNode) geom_node = new GeomNode(egg_bin->get_name());
|
geom_node = new GeomNode(egg_bin->get_name());
|
||||||
if (render_state->_hidden) {
|
if (render_state->_hidden) {
|
||||||
parent->add_stashed(geom_node);
|
parent->add_stashed(geom_node);
|
||||||
} else {
|
} else {
|
||||||
parent->add_child(geom_node);
|
parent->add_child(geom_node);
|
||||||
}
|
}
|
||||||
geom_node->add_geom(geom, render_state->_state);
|
}
|
||||||
|
|
||||||
|
geom_node->add_geom(geom, render_state->_state);
|
||||||
|
if (egg_show_normals) {
|
||||||
|
show_normals(vertex_pool, geom_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggLoader::show_normals
|
||||||
|
// Access: Private
|
||||||
|
// Description: In the presence of egg-show-normals, generate some
|
||||||
|
// additional geometry to represent the normals,
|
||||||
|
// tangents, and binormals of each vertex.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggLoader::
|
||||||
|
show_normals(EggVertexPool *vertex_pool, GeomNode *geom_node) {
|
||||||
|
PT(GeomPrimitive) primitive = new GeomLines(Geom::UH_static);
|
||||||
|
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3cp();
|
||||||
|
PT(GeomVertexData) vertex_data =
|
||||||
|
new GeomVertexData(vertex_pool->get_name(), format, Geom::UH_static);
|
||||||
|
|
||||||
|
GeomVertexWriter vertex(vertex_data, InternalName::get_vertex());
|
||||||
|
GeomVertexWriter color(vertex_data, InternalName::get_color());
|
||||||
|
|
||||||
|
EggVertexPool::const_iterator vi;
|
||||||
|
for (vi = vertex_pool->begin(); vi != vertex_pool->end(); ++vi) {
|
||||||
|
EggVertex *vert = (*vi);
|
||||||
|
LPoint3d pos = vert->get_pos3();
|
||||||
|
|
||||||
|
if (vert->has_normal()) {
|
||||||
|
vertex.add_data3f(LCAST(float, pos));
|
||||||
|
vertex.add_data3f(LCAST(float, pos + vert->get_normal() * egg_normal_scale));
|
||||||
|
color.add_data4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
color.add_data4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
primitive->add_next_vertices(2);
|
||||||
|
primitive->close_primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also look for tangents and binormals in each texture coordinate
|
||||||
|
// set.
|
||||||
|
EggVertex::const_uv_iterator uvi;
|
||||||
|
for (uvi = vert->uv_begin(); uvi != vert->uv_end(); ++uvi) {
|
||||||
|
EggVertexUV *uv_obj = (*uvi);
|
||||||
|
if (uv_obj->has_tangent()) {
|
||||||
|
vertex.add_data3f(LCAST(float, pos));
|
||||||
|
vertex.add_data3f(LCAST(float, pos + uv_obj->get_tangent() * egg_normal_scale));
|
||||||
|
color.add_data4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
color.add_data4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
primitive->add_next_vertices(2);
|
||||||
|
primitive->close_primitive();
|
||||||
|
}
|
||||||
|
if (uv_obj->has_binormal()) {
|
||||||
|
vertex.add_data3f(LCAST(float, pos));
|
||||||
|
vertex.add_data3f(LCAST(float, pos + uv_obj->get_binormal() * egg_normal_scale));
|
||||||
|
color.add_data4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
color.add_data4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
primitive->add_next_vertices(2);
|
||||||
|
primitive->close_primitive();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
PT(Geom) geom = new Geom;
|
||||||
|
geom->set_vertex_data(vertex_data);
|
||||||
|
geom->add_primitive(primitive);
|
||||||
|
geom_node->add_geom(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1659,8 +1723,8 @@ make_vertex_data(const EggRenderState *render_state,
|
|||||||
Geom::NT_packed_dabc, Geom::C_color);
|
Geom::NT_packed_dabc, Geom::C_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_string uv_names;
|
vector_string uv_names, tbn_names;
|
||||||
vertex_pool->get_uv_names(uv_names);
|
vertex_pool->get_uv_names(uv_names, tbn_names);
|
||||||
vector_string::const_iterator ni;
|
vector_string::const_iterator ni;
|
||||||
for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
|
for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
|
||||||
string name = (*ni);
|
string name = (*ni);
|
||||||
@ -1669,8 +1733,19 @@ make_vertex_data(const EggRenderState *render_state,
|
|||||||
}
|
}
|
||||||
PT(InternalName) iname = InternalName::get_texcoord_name(name);
|
PT(InternalName) iname = InternalName::get_texcoord_name(name);
|
||||||
array_format->add_column
|
array_format->add_column
|
||||||
(iname, 2,
|
(iname, 2, Geom::NT_float32, Geom::C_texcoord);
|
||||||
Geom::NT_float32, Geom::C_texcoord);
|
}
|
||||||
|
for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
|
||||||
|
string name = (*ni);
|
||||||
|
if (name == "default") {
|
||||||
|
name = string();
|
||||||
|
}
|
||||||
|
PT(InternalName) iname = InternalName::get_tangent_name(name);
|
||||||
|
array_format->add_column
|
||||||
|
(iname, 3, Geom::NT_float32, Geom::C_vector);
|
||||||
|
iname = InternalName::get_binormal_name(name);
|
||||||
|
array_format->add_column
|
||||||
|
(iname, 3, Geom::NT_float32, Geom::C_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
PT(GeomVertexFormat) temp_format = new GeomVertexFormat(array_format);
|
PT(GeomVertexFormat) temp_format = new GeomVertexFormat(array_format);
|
||||||
@ -1867,6 +1942,19 @@ make_vertex_data(const EggRenderState *render_state,
|
|||||||
gvw.add_data2f(LCAST(float, duv));
|
gvw.add_data2f(LCAST(float, duv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also add the tangent and binormal, if present.
|
||||||
|
if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
|
||||||
|
PT(InternalName) iname = InternalName::get_tangent_name(name);
|
||||||
|
gvw.set_column(iname);
|
||||||
|
if (gvw.has_column()) {
|
||||||
|
LVector3d tangent = egg_uv->get_tangent();
|
||||||
|
LVector3d binormal = egg_uv->get_binormal();
|
||||||
|
gvw.add_data3f(LCAST(float, tangent));
|
||||||
|
gvw.set_column(InternalName::get_binormal_name(name));
|
||||||
|
gvw.add_data3f(LCAST(float, binormal));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_dynamic) {
|
if (is_dynamic) {
|
||||||
|
@ -105,7 +105,9 @@ private:
|
|||||||
GeomPrimitive::ShadeModel _shade_model;
|
GeomPrimitive::ShadeModel _shade_model;
|
||||||
};
|
};
|
||||||
typedef pmap<PrimitiveUnifier, PT(GeomPrimitive) > Primitives;
|
typedef pmap<PrimitiveUnifier, PT(GeomPrimitive) > Primitives;
|
||||||
|
|
||||||
|
void show_normals(EggVertexPool *vertex_pool, GeomNode *geom_node);
|
||||||
|
|
||||||
void make_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
|
void make_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
|
||||||
const LMatrix4d &mat);
|
const LMatrix4d &mat);
|
||||||
void make_old_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
|
void make_old_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
|
||||||
|
@ -136,6 +136,19 @@ get_tangent() {
|
|||||||
return _tangent;
|
return _tangent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: InternalName::get_tangent_name
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns the InternalName "tangent.name", where name
|
||||||
|
// is the supplied string. This is the column header
|
||||||
|
// for the tangent associated with the named texture
|
||||||
|
// coordinate set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE PT(InternalName) InternalName::
|
||||||
|
get_tangent_name(const string &name) {
|
||||||
|
return get_tangent()->append(name);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: InternalName::get_binormal
|
// Function: InternalName::get_binormal
|
||||||
// Access: Published, Static
|
// Access: Published, Static
|
||||||
@ -155,6 +168,19 @@ get_binormal() {
|
|||||||
return _binormal;
|
return _binormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: InternalName::get_binormal_name
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns the InternalName "binormal.name", where name
|
||||||
|
// is the supplied string. This is the column header
|
||||||
|
// for the binormal associated with the named texture
|
||||||
|
// coordinate set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE PT(InternalName) InternalName::
|
||||||
|
get_binormal_name(const string &name) {
|
||||||
|
return get_binormal()->append(name);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: InternalName::get_texcoord
|
// Function: InternalName::get_texcoord
|
||||||
// Access: Published, Static
|
// Access: Published, Static
|
||||||
|
@ -67,7 +67,9 @@ PUBLISHED:
|
|||||||
INLINE static PT(InternalName) get_vertex();
|
INLINE static PT(InternalName) get_vertex();
|
||||||
INLINE static PT(InternalName) get_normal();
|
INLINE static PT(InternalName) get_normal();
|
||||||
INLINE static PT(InternalName) get_tangent();
|
INLINE static PT(InternalName) get_tangent();
|
||||||
|
INLINE static PT(InternalName) get_tangent_name(const string &name);
|
||||||
INLINE static PT(InternalName) get_binormal();
|
INLINE static PT(InternalName) get_binormal();
|
||||||
|
INLINE static PT(InternalName) get_binormal_name(const string &name);
|
||||||
INLINE static PT(InternalName) get_texcoord();
|
INLINE static PT(InternalName) get_texcoord();
|
||||||
INLINE static PT(InternalName) get_texcoord_name(const string &name);
|
INLINE static PT(InternalName) get_texcoord_name(const string &name);
|
||||||
INLINE static PT(InternalName) get_color();
|
INLINE static PT(InternalName) get_color();
|
||||||
|
@ -87,6 +87,18 @@ add_normals_options() {
|
|||||||
("nn", "", 48,
|
("nn", "", 48,
|
||||||
"Preserve normals exactly as they are. This is the default.",
|
"Preserve normals exactly as they are. This is the default.",
|
||||||
&EggBase::dispatch_normals, NULL, &preserve);
|
&EggBase::dispatch_normals, NULL, &preserve);
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("tbn", "name", 48,
|
||||||
|
"Compute tangent and binormal for the named texture coordinate "
|
||||||
|
"set(s). The name may include wildcard characters such as * and ?; "
|
||||||
|
"use \"*\" to recompute tangent and binormal for all texture coordinate "
|
||||||
|
"sets. "
|
||||||
|
"The normal must already exist or have been computed via one of the "
|
||||||
|
"above options. The tangent and binormal are used to implement "
|
||||||
|
"bump mapping and related texture-based lighting effects. This option "
|
||||||
|
"may be repeated as necessary to name multiple texture coordinate sets.",
|
||||||
|
&EggBase::dispatch_vector_string, NULL, &_tbn_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -66,6 +66,7 @@ protected:
|
|||||||
};
|
};
|
||||||
NormalsMode _normals_mode;
|
NormalsMode _normals_mode;
|
||||||
double _normals_threshold;
|
double _normals_threshold;
|
||||||
|
vector_string _tbn_names;
|
||||||
|
|
||||||
bool _got_transform;
|
bool _got_transform;
|
||||||
LMatrix4d _transform;
|
LMatrix4d _transform;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "compose_matrix.h"
|
#include "compose_matrix.h"
|
||||||
|
#include "globPattern.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: EggWriter::Constructor
|
// Function: EggWriter::Constructor
|
||||||
@ -161,6 +162,14 @@ post_process_egg_file() {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (vector_string::const_iterator si = _tbn_names.begin();
|
||||||
|
si != _tbn_names.end();
|
||||||
|
++si) {
|
||||||
|
GlobPattern uv_name(*si);
|
||||||
|
nout << "Computing tangent and binormal for \"" << uv_name << "\"\n";
|
||||||
|
_data->recompute_tangent_binormal(uv_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user