Add patch from community member teedee for egg <Aux> syntax

This commit is contained in:
David Rose 2011-11-17 19:39:29 +00:00
parent b8497a0478
commit be7f483478
11 changed files with 348 additions and 4 deletions

View File

@ -720,6 +720,18 @@ appear before they are referenced.
<UV> [name] { u v [w] <Tangent> { x y z } <Binormal> { x y z } }
<AUX> name { x y z w }
This specifies some named per-vertex auxiliary data which is
imported from the egg file without further interpretation by
Panda. The auxiliary data is copied to the vertex data under a
column with the specified name. Presumably the data will have
meaning to custom code or a custom shader. Like named UV's, there
may be multiple Aux entries for a given vertex, each with a
different name.
<DynamicVertexPool> name { vertices }
A dynamic vertex pool is similar to a vertex pool in most respects,

View File

@ -52,6 +52,7 @@
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "eggVertexUV.h"
#include "eggVertexAux.h"
#include "eggXfmAnimData.h"
#include "eggXfmSAnim.h"
@ -207,6 +208,7 @@ init_libegg() {
EggVertex::init_type();
EggVertexPool::init_type();
EggVertexUV::init_type();
EggVertexAux::init_type();
EggXfmAnimData::init_type();
EggXfmSAnim::init_type();
}

View File

@ -195,6 +195,17 @@ has_uv() const {
return has_uv("");
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::has_aux
// Access: Published
// Description: Returns true if the vertex has any auxiliary
// data, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EggVertex::
has_aux() const {
return (_aux_map.size() != 0);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_uv
// Access: Published
@ -239,6 +250,16 @@ clear_uv() {
_uv_map.clear();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::clear_aux
// Access: Published
// Description: Removes all auxiliary data from the vertex.
////////////////////////////////////////////////////////////////////
INLINE void EggVertex::
clear_aux() {
_aux_map.clear();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::uv_begin
// Access: Public
@ -253,6 +274,20 @@ uv_begin() const {
return _uv_map.begin();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::aux_begin
// Access: Public
// Description: Returns an iterator that allows walking through the
// complete set of auxiliary data on the vertex.
//
// This interface is not safe to use outside of
// PANDAEGG.DLL.
////////////////////////////////////////////////////////////////////
INLINE EggVertex::const_aux_iterator EggVertex::
aux_begin() const {
return _aux_map.begin();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::uv_end
// Access: Public
@ -267,6 +302,20 @@ uv_end() const {
return _uv_map.end();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::aux_end
// Access: Public
// Description: Returns an iterator that allows walking through the
// complete set of auxiliary data on the vertex.
//
// This interface is not safe to use outside of
// PANDAEGG.DLL.
////////////////////////////////////////////////////////////////////
INLINE EggVertex::const_aux_iterator EggVertex::
aux_end() const {
return _aux_map.end();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::uv_size
// Access: Public
@ -277,6 +326,16 @@ uv_size() const {
return _uv_map.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::aux_size
// Access: Public
// Description: Returns the number of auxiliary datas on the vertex.
////////////////////////////////////////////////////////////////////
INLINE EggVertex::aux_size_type EggVertex::
aux_size() const {
return _aux_map.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_index
// Access: Published

View File

@ -59,7 +59,8 @@ EggVertex(const EggVertex &copy)
_external_index(copy._external_index),
_pos(copy._pos),
_num_dimensions(copy._num_dimensions),
_uv_map(copy._uv_map)
_uv_map(copy._uv_map),
_aux_map(copy._aux_map)
{
_pool = NULL;
_forward_reference = false;
@ -84,6 +85,7 @@ operator = (const EggVertex &copy) {
_pos = copy._pos;
_num_dimensions = copy._num_dimensions;
_uv_map = copy._uv_map;
_aux_map = copy._aux_map;
test_pref_integrity();
test_gref_integrity();
@ -143,11 +145,27 @@ has_uvw(const string &name) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::has_aux
// Access: Published
// Description: Returns true if the vertex has the named
// auxiliary data quadruple.
////////////////////////////////////////////////////////////////////
bool EggVertex::
has_aux(const string &name) const {
AuxMap::const_iterator xi = _aux_map.find(name);
if (xi != _aux_map.end()) {
EggVertexAux *aux_obj = (*xi).second;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_uv
// Access: Published
// Description: Returns the named UV coordinate pair on the vertex.
// vertex. It is an error to call this if has_uv(name)
// It is an error to call this if has_uv(name)
// returned false.
////////////////////////////////////////////////////////////////////
LTexCoordd EggVertex::
@ -161,7 +179,7 @@ get_uv(const string &name) const {
// Function: EggVertex::get_uvw
// Access: Published
// Description: Returns the named UV coordinate triple on the vertex.
// vertex. It is an error to call this if has_uvw(name)
// It is an error to call this if has_uvw(name)
// returned false.
////////////////////////////////////////////////////////////////////
const LTexCoord3d &EggVertex::
@ -171,6 +189,20 @@ get_uvw(const string &name) const {
return (*ui).second->get_uvw();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_aux
// Access: Published
// Description: Returns the named auxiliary data quadruple on the
// vertex. It is an error to call this if has_aux(name)
// returned false.
////////////////////////////////////////////////////////////////////
const LVecBase4d &EggVertex::
get_aux(const string &name) const {
AuxMap::const_iterator xi = _aux_map.find(name);
nassertr(xi != _aux_map.end(), LVecBase4d::zero());
return (*xi).second->get_aux();
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_uv
// Access: Published
@ -216,6 +248,27 @@ set_uvw(const string &name, const LTexCoord3d &uvw) {
nassertv(get_uvw(fname) == uvw);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_aux
// Access: Published
// Description: Sets the indicated auxiliary data quadruple on the
// vertex. This replaces any auxiliary data with the
// same name already on the vertex.
////////////////////////////////////////////////////////////////////
void EggVertex::
set_aux(const string &name, const LVecBase4d &aux) {
PT(EggVertexAux) &aux_obj = _aux_map[name];
if (aux_obj.is_null()) {
aux_obj = new EggVertexAux(name, aux);
} else {
aux_obj = new EggVertexAux(*aux_obj);
aux_obj->set_aux(aux);
}
nassertv(get_aux(name) == aux);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_uv_obj
// Access: Published
@ -235,6 +288,24 @@ get_uv_obj(const string &name) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::get_aux_obj
// Access: Published
// Description: Returns the named EggVertexAux object, which defines
// the auxiliary data for this name. This object might
// be shared between multiple vertices. You should not
// attempt to modify this object; instead, call
// modify_aux_object to return a modifiable pointer.
////////////////////////////////////////////////////////////////////
const EggVertexAux *EggVertex::
get_aux_obj(const string &name) const {
AuxMap::const_iterator xi = _aux_map.find(name);
if (xi != _aux_map.end()) {
return (*xi).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::modify_uv_obj
// Access: Published
@ -257,6 +328,28 @@ modify_uv_obj(const string &name) {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::modify_aux_obj
// Access: Published
// Description: Returns a modifiable pointer to the named EggVertexAux
// object, which defines the auxiliary data for
// this name. Returns NULL if there is no such
// named UV object.
////////////////////////////////////////////////////////////////////
EggVertexAux *EggVertex::
modify_aux_obj(const string &name) {
AuxMap::iterator xi = _aux_map.find(name);
if (xi != _aux_map.end()) {
if ((*xi).second->get_ref_count() != 1) {
// Copy on write.
(*xi).second = new EggVertexAux(*(*xi).second);
}
return (*xi).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_uv_obj
// Access: Published
@ -269,6 +362,18 @@ set_uv_obj(EggVertexUV *uv) {
_uv_map[uv->get_name()] = uv;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::set_aux_obj
// Access: Published
// Description: Sets the indicated EggVertexAux on the vertex.
// This replaces any auxiliary data with the same
// name already on the vertex.
////////////////////////////////////////////////////////////////////
void EggVertex::
set_aux_obj(EggVertexAux *aux) {
_aux_map[aux->get_name()] = aux;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::clear_uv
// Access: Published
@ -280,6 +385,16 @@ clear_uv(const string &name) {
_uv_map.erase(EggVertexUV::filter_name(name));
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::clear_aux
// Access: Published
// Description: Removes the named auxiliary data from the vertex.
///////////////////////////////////////////////////////////////////
void EggVertex::
clear_aux(const string &name) {
_aux_map.erase(name);
}
///////////////////////////////////////////////////////////////////
// Class : GroupRefEntry
@ -335,6 +450,11 @@ write(ostream &out, int indent_level) const {
(*ui).second->write(out, indent_level + 2);
}
AuxMap::const_iterator xi;
for (xi = _aux_map.begin(); xi != _aux_map.end(); ++xi) {
(*xi).second->write(out, indent_level + 2);
}
EggAttributes::write(out, indent_level+2);
_dxyzs.write(out, indent_level + 2, "<Dxyz>", 3);
@ -427,6 +547,33 @@ compare_to(const EggVertex &other) const {
return 1;
}
// Merge-compare the aux maps.
AuxMap::const_iterator ci, di;
ci = _aux_map.begin();
di = other._aux_map.begin();
while (ci != _aux_map.end() && di != other._aux_map.end()) {
if ((*ci).first < (*di).first) {
return -1;
} else if ((*di).first < (*ci).first) {
return 1;
} else {
int compare = (*ci).second->compare_to(*(*di).second);
if (compare != 0) {
return compare;
}
}
++ci;
++di;
}
if (di != other._aux_map.end()) {
return -1;
}
if (ci != _aux_map.end()) {
return 1;
}
return EggAttributes::compare_to(other);
}

View File

@ -21,6 +21,7 @@
#include "eggAttributes.h"
#include "eggMorphList.h"
#include "eggVertexUV.h"
#include "eggVertexAux.h"
#include "referenceCount.h"
#include "luse.h"
@ -42,11 +43,17 @@ public:
typedef pset<EggGroup *> GroupRef;
typedef pmultiset<EggPrimitive *> PrimitiveRef;
typedef pmap< string, PT(EggVertexUV) > UVMap;
typedef pmap< string, PT(EggVertexAux) > AuxMap;
typedef second_of_pair_iterator<UVMap::const_iterator> uv_iterator;
typedef uv_iterator const_uv_iterator;
typedef UVMap::size_type uv_size_type;
typedef second_of_pair_iterator<AuxMap::const_iterator> aux_iterator;
typedef aux_iterator const_aux_iterator;
typedef AuxMap::size_type aux_size_type;
PUBLISHED:
EggVertex();
EggVertex(const EggVertex &copy);
@ -92,11 +99,25 @@ PUBLISHED:
void set_uv_obj(EggVertexUV *vertex_uv);
void clear_uv(const string &name);
INLINE bool has_aux() const;
INLINE void clear_aux();
bool has_aux(const string &name) const;
const LVecBase4d &get_aux(const string &name) const;
void set_aux(const string &name, const LVecBase4d &aux);
const EggVertexAux *get_aux_obj(const string &name) const;
EggVertexAux *modify_aux_obj(const string &name);
void set_aux_obj(EggVertexAux *vertex_aux);
void clear_aux(const string &name);
public:
INLINE const_uv_iterator uv_begin() const;
INLINE const_uv_iterator uv_end() const;
INLINE uv_size_type uv_size() const;
INLINE const_aux_iterator aux_begin() const;
INLINE const_aux_iterator aux_end() const;
INLINE aux_size_type aux_size() const;
PUBLISHED:
INLINE int get_index() const;
@ -152,6 +173,7 @@ private:
PrimitiveRef _pref;
UVMap _uv_map;
AuxMap _aux_map;
public:
static TypeHandle get_class_type() {

View File

@ -327,6 +327,25 @@ has_uvs() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::has_aux
// Access: Public
// Description: Returns true if any vertex in the pool has
// auxiliary data defined, false if none of them do.
////////////////////////////////////////////////////////////////////
bool EggVertexPool::
has_aux() const {
IndexVertices::const_iterator ivi;
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
EggVertex *vertex = (*ivi).second;
if (vertex->has_aux()) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::get_uv_names
// Access: Public
@ -370,6 +389,31 @@ get_uv_names(vector_string &uv_names, vector_string &uvw_names,
}
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::get_aux_names
// Access: Public
// Description: Returns the list of auxiliary data names that are
// defined by any vertices in the pool.
////////////////////////////////////////////////////////////////////
void EggVertexPool::
get_aux_names(vector_string &aux_names) const {
pset<string> aux_names_set;
IndexVertices::const_iterator ivi;
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
EggVertex *vertex = (*ivi).second;
EggVertex::const_aux_iterator uvi;
for (uvi = vertex->aux_begin(); uvi != vertex->aux_end(); ++uvi) {
EggVertexAux *aux_obj = (*uvi);
aux_names_set.insert(aux_obj->get_name());
}
}
pset<string>::const_iterator si;
for (si = aux_names_set.begin(); si != aux_names_set.end(); ++si) {
aux_names.push_back(*si);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::begin()
// Access: Public

View File

@ -96,8 +96,10 @@ PUBLISHED:
bool has_nonwhite_colors() const;
void check_overall_color(bool &has_overall_color, LColor &overall_color) const;
bool has_uvs() const;
bool has_aux() const;
void get_uv_names(vector_string &uv_names, vector_string &uvw_names,
vector_string &tbn_names) const;
void get_aux_names(vector_string &aux_names) const;
public:
// Can be used to traverse all the vertices in index number order.

View File

@ -20,6 +20,7 @@
#include "eggVertex.cxx"
#include "eggVertexPool.cxx"
#include "eggVertexUV.cxx"
#include "eggVertexAux.cxx"
#include "eggXfmAnimData.cxx"
#include "eggXfmSAnim.cxx"
#include "pt_EggMaterial.cxx"

View File

@ -351,6 +351,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
accept();
return ANIMPRELOAD;
}
"<AUX>" {
accept();
return AUX;
}
"<BEZIERCURVE>" {
accept();
return BEZIERCURVE;

View File

@ -14,6 +14,7 @@
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "eggVertexUV.h"
#include "eggVertexAux.h"
#include "eggPolygon.h"
#include "eggCompositePrimitive.h"
#include "eggTriangleFan.h"
@ -172,7 +173,7 @@ egg_cleanup_parser() {
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
%token TABLE TABLE_V TAG TANGENT TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
%token TREF TRIANGLEFAN TRIANGLESTRIP
%token TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
%token TRIM TXT UKNOTS UV AUX VKNOTS VERTEX VERTEXANIM
%token VERTEXPOOL VERTEXREF
%token XFMANIM XFMSANIM
@ -999,6 +1000,21 @@ vertex_body:
vertex_uv_body '}'
{
egg_stack.pop_back();
}
| vertex_body AUX required_name '{'
{
EggVertex *vertex = DCAST(EggVertex, egg_stack.back());
EggVertexAux *aux = new EggVertexAux($3, LVecBase4d::zero());
egg_stack.push_back(aux);
if (vertex->has_aux($3)) {
eggyywarning("Ignoring repeated Aux name " + $3);
} else {
vertex->set_aux_obj(aux);
}
}
vertex_aux_body '}'
{
egg_stack.pop_back();
}
| vertex_body NORMAL '{' vertex_normal_body '}'
| vertex_body RGBA '{' vertex_color_body '}'
@ -1087,6 +1103,20 @@ vertex_uv_body:
}
;
/*
* vertex_aux_body
*
* enter: TOS is EggVertex.
* exit: vertex Aux value has been filled.
*
*/
vertex_aux_body:
| real real real real
{
DCAST(EggVertexAux, egg_stack.back())->set_aux(LVecBase4d($1, $2, $3, $4));
}
;
/*
* vertex_normal_body
*

View File

@ -2243,6 +2243,15 @@ make_vertex_data(const EggRenderState *render_state,
(iname, 3, Geom::NT_stdfloat, Geom::C_vector);
}
vector_string aux_names;
vertex_pool->get_aux_names(aux_names);
for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
string name = (*ni);
PT(InternalName) iname = InternalName::make(name);
array_format->add_column
(iname, 4, Geom::NT_stdfloat, Geom::C_other);
}
PT(GeomVertexFormat) temp_format = new GeomVertexFormat(array_format);
PT(TransformBlendTable) blend_table;
@ -2454,6 +2463,18 @@ make_vertex_data(const EggRenderState *render_state,
}
}
EggVertex::const_aux_iterator auxi;
for (auxi = vertex->aux_begin(); auxi != vertex->aux_end(); ++auxi) {
EggVertexAux *egg_aux = (*auxi);
LVecBase4d aux = egg_aux->get_aux();
string name = egg_aux->get_name();
PT(InternalName) iname = InternalName::make(name);
gvw.set_column(iname);
gvw.set_data4d(aux);
}
if (is_dynamic) {
// Figure out the transforms affecting this particular vertex.
TransformBlend blend;