Add EggVertex::make_average(v1, v2)

This commit is contained in:
rdb
2015-02-08 19:51:18 +01:00
parent aec80426a3
commit 91568b02bc
6 changed files with 179 additions and 11 deletions
+119
View File
@@ -398,6 +398,125 @@ clear_aux(const string &name) {
_aux_map.erase(name);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertex::make_average
// Access: Published, Static
// Description: Creates a new vertex that lies in between the two
// given vertices. The attributes for the UV sets
// they have in common are averaged.
//
// Both vertices need to be either in no pool, or in
// the same pool. In the latter case, the new vertex
// will be placed in that pool.
///////////////////////////////////////////////////////////////////
PT(EggVertex) EggVertex::
make_average(const EggVertex *first, const EggVertex *second) {
PT(EggVertexPool) pool = first->get_pool();
nassertr(pool == second->get_pool(), NULL);
// If both vertices are in a pool, the new vertex will be part of
// the pool as well.
PT(EggVertex) middle;
if (pool == NULL) {
middle = new EggVertex;
} else {
middle = pool->make_new_vertex();
}
middle->set_pos4((first->get_pos4() + second->get_pos4()) / 2);
if (first->has_normal() && second->has_normal()) {
LNormald normal = (first->get_normal() + second->get_normal()) / 2;
normal.normalize();
middle->set_normal(normal);
}
if (first->has_color() && second->has_color()) {
middle->set_color((first->get_color() + second->get_color()) / 2);
}
// Average out the EggVertexUV objects, but only for the UV sets
// that they have in common.
const_uv_iterator it;
for (it = first->uv_begin(); it != first->uv_end(); ++it) {
const EggVertexUV *first_uv = it->second;
const EggVertexUV *second_uv = second->get_uv_obj(it->first);
if (first_uv != NULL && second_uv != NULL) {
middle->set_uv_obj(EggVertexUV::make_average(first_uv, second_uv));
}
}
// Same for EggVertexAux.
const_aux_iterator ai;
for (ai = first->aux_begin(); ai != first->aux_end(); ++ai) {
const EggVertexAux *first_aux = ai->second;
const EggVertexAux *second_aux = second->get_aux_obj(ai->first);
if (first_aux != NULL && second_aux != NULL) {
middle->set_aux_obj(EggVertexAux::make_average(first_aux, second_aux));
}
}
// Now process the morph targets.
EggMorphVertexList::const_iterator vi, vi2;
for (vi = first->_dxyzs.begin(); vi != first->_dxyzs.end(); ++vi) {
for (vi2 = second->_dxyzs.begin(); vi2 != second->_dxyzs.end(); ++vi2) {
if (vi->get_name() == vi2->get_name()) {
middle->_dxyzs.insert(EggMorphVertex(vi->get_name(),
(vi->get_offset() + vi2->get_offset()) / 2));
break;
}
}
}
EggMorphNormalList::const_iterator ni, ni2;
for (ni = first->_dxyzs.begin(); ni != first->_dxyzs.end(); ++ni) {
for (ni2 = second->_dxyzs.begin(); ni2 != second->_dxyzs.end(); ++ni2) {
if (ni->get_name() == ni2->get_name()) {
middle->_dnormals.insert(EggMorphNormal(ni->get_name(),
(ni->get_offset() + ni2->get_offset()) / 2));
break;
}
}
}
EggMorphColorList::const_iterator ci, ci2;
for (ci = first->_drgbas.begin(); ci != first->_drgbas.end(); ++ci) {
for (ci2 = second->_drgbas.begin(); ci2 != second->_drgbas.end(); ++ci2) {
if (ci->get_name() == ci2->get_name()) {
middle->_drgbas.insert(EggMorphColor(ci->get_name(),
(ci->get_offset() + ci2->get_offset()) / 2));
break;
}
}
}
// Now merge the vertex memberships.
GroupRef::iterator gi;
for (gi = first->_gref.begin(); gi != first->_gref.end(); ++gi) {
EggGroup *group = *gi;
if (second->_gref.count(group)) {
group->set_vertex_membership(middle,
(group->get_vertex_membership(first) +
group->get_vertex_membership(second)) / 2.);
} else {
// Hmm, unfortunate, only one of the vertices is member of this
// group, so we can't make an average. We'll have to assign the
// only group membership we have.
group->set_vertex_membership(middle, group->get_vertex_membership(first));
}
}
// Also assign memberships to the grefs in the second vertex that
// aren't part of the first vertex.
for (gi = second->_gref.begin(); gi != second->_gref.end(); ++gi) {
EggGroup *group = *gi;
if (second->_gref.count(group) == 0) {
group->set_vertex_membership(middle, group->get_vertex_membership(second));
}
}
return middle;
}
///////////////////////////////////////////////////////////////////
// Class : GroupRefEntry
+3
View File
@@ -109,6 +109,9 @@ PUBLISHED:
void set_aux_obj(EggVertexAux *vertex_aux);
void clear_aux(const string &name);
static PT(EggVertex) make_average(const EggVertex *first,
const EggVertex *second);
public:
INLINE const_uv_iterator uv_begin() const;
INLINE const_uv_iterator uv_end() const;
+20 -5
View File
@@ -22,7 +22,7 @@ TypeHandle EggVertexAux::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexAux::
EggVertexAux(const string &name, const LVecBase4d &aux) :
@@ -34,7 +34,7 @@ EggVertexAux(const string &name, const LVecBase4d &aux) :
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::Copy Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexAux::
EggVertexAux(const EggVertexAux &copy) :
@@ -46,7 +46,7 @@ EggVertexAux(const EggVertexAux &copy) :
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::Copy Assignment Operator
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexAux &EggVertexAux::
operator = (const EggVertexAux &copy) {
@@ -59,16 +59,31 @@ operator = (const EggVertexAux &copy) {
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::Destructor
// Access: Published, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexAux::
~EggVertexAux() {
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::make_average
// Access: Published, Static
// Description: Creates a new EggVertexAux that contains the
// averaged values of the two given objects. It is
// an error if they don't have the same name.
///////////////////////////////////////////////////////////////////
PT(EggVertexAux) EggVertexAux::
make_average(const EggVertexAux *first, const EggVertexAux *second) {
nassertr(first->get_name() == second->get_name(), NULL);
LVecBase4d aux = (first->_aux + second->_aux) / 2;
return new EggVertexAux(first->get_name(), aux);
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexAux::write
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void EggVertexAux::
write(ostream &out, int indent_level) const {
+3
View File
@@ -42,6 +42,9 @@ PUBLISHED:
INLINE const LVecBase4d &get_aux() const;
INLINE void set_aux(const LVecBase4d &aux);
static PT(EggVertexAux) make_average(const EggVertexAux *first,
const EggVertexAux *second);
void write(ostream &out, int indent_level) const;
int compare_to(const EggVertexAux &other) const;
+31 -6
View File
@@ -22,7 +22,7 @@ TypeHandle EggVertexUV::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV::
EggVertexUV(const string &name, const LTexCoordd &uv) :
@@ -38,7 +38,7 @@ EggVertexUV(const string &name, const LTexCoordd &uv) :
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV::
EggVertexUV(const string &name, const LTexCoord3d &uvw) :
@@ -54,7 +54,7 @@ EggVertexUV(const string &name, const LTexCoord3d &uvw) :
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Copy Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV::
EggVertexUV(const EggVertexUV &copy) :
@@ -70,7 +70,7 @@ EggVertexUV(const EggVertexUV &copy) :
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Copy Assignment Operator
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV &EggVertexUV::
operator = (const EggVertexUV &copy) {
@@ -87,12 +87,37 @@ operator = (const EggVertexUV &copy) {
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::Destructor
// Access: Published, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
EggVertexUV::
~EggVertexUV() {
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::make_average
// Access: Published, Static
// Description: Creates a new EggVertexUV that contains the
// averaged values of the two given objects. It is
// an error if they don't have the same name.
///////////////////////////////////////////////////////////////////
PT(EggVertexUV) EggVertexUV::
make_average(const EggVertexUV *first, const EggVertexUV *second) {
nassertr(first->get_name() == second->get_name(), NULL);
int flags = first->_flags & second->_flags;
LTexCoord3d uvw = (first->_uvw + second->_uvw) / 2;
PT(EggVertexUV) new_obj = new EggVertexUV(first->get_name(), uvw);
new_obj->_flags = flags;
new_obj->_tangent = (first->_tangent + second->_tangent) / 2;
new_obj->_binormal = (first->_binormal + second->_binormal) / 2;
// Normalize because we're polite.
new_obj->_tangent.normalize();
new_obj->_binormal.normalize();
return new_obj;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::transform
// Access: Published, Virtual
@@ -115,7 +140,7 @@ transform(const LMatrix4d &mat) {
////////////////////////////////////////////////////////////////////
// Function: EggVertexUV::write
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void EggVertexUV::
write(ostream &out, int indent_level) const {
+3
View File
@@ -57,6 +57,9 @@ PUBLISHED:
INLINE void set_binormal(const LNormald &binormal);
INLINE void clear_binormal();
static PT(EggVertexUV) make_average(const EggVertexUV *first,
const EggVertexUV *second);
void transform(const LMatrix4d &mat);
void write(ostream &out, int indent_level) const;