|
|
@@ -18,8 +18,17 @@
|
|
|
|
|
|
#include "bamToEgg.h"
|
|
|
|
|
|
-#include "node.h"
|
|
|
-#include "LODNode.h"
|
|
|
+#include "pandaNode.h"
|
|
|
+#include "workingNodePath.h"
|
|
|
+#include "nodePath.h"
|
|
|
+#include "billboardEffect.h"
|
|
|
+#include "renderEffects.h"
|
|
|
+#include "transformState.h"
|
|
|
+#include "colorScaleAttrib.h"
|
|
|
+#include "colorAttrib.h"
|
|
|
+#include "textureAttrib.h"
|
|
|
+#include "cullFaceAttrib.h"
|
|
|
+#include "lodNode.h"
|
|
|
#include "geomNode.h"
|
|
|
#include "geom.h"
|
|
|
#include "geomTri.h"
|
|
|
@@ -33,153 +42,9 @@
|
|
|
#include "eggTexture.h"
|
|
|
#include "eggMaterial.h"
|
|
|
#include "somethingToEggConverter.h"
|
|
|
+#include "dcast.h"
|
|
|
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::Constructor
|
|
|
-// Access: Public
|
|
|
-// Description:
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-BamToEgg::GeomState::
|
|
|
-GeomState() {
|
|
|
- _mat = LMatrix4f::ident_mat();
|
|
|
- _tex_mat = LMatrix4f::ident_mat();
|
|
|
- _color_mat = LMatrix4f::ident_mat();
|
|
|
- _alpha_scale = 1.0;
|
|
|
- _alpha_offset = 0.0;
|
|
|
- _tex = (Texture *)NULL;
|
|
|
- _bface = false;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::get_net_state
|
|
|
-// Access: Public
|
|
|
-// Description: Gets the accumulated state of the indicated node (and
|
|
|
-// its corresponding ArcChain) into the GeomState.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-get_net_state(Node *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
- AllTransitionsWrapper atw;
|
|
|
-
|
|
|
- wrt(node, chain.begin(), chain.end(),
|
|
|
- (Node *)NULL,
|
|
|
- atw, RenderRelation::get_class_type());
|
|
|
-
|
|
|
- // Check for transform space.
|
|
|
- const TransformTransition *tt;
|
|
|
- if (get_transition_into(tt, atw)) {
|
|
|
- _mat = tt->get_matrix();
|
|
|
- LMatrix4f inv = LCAST(float, egg_parent->get_vertex_frame_inv());
|
|
|
- _mat = _mat * inv;
|
|
|
- }
|
|
|
-
|
|
|
- // Check for texture matrix.
|
|
|
- const TexMatrixTransition *tmt;
|
|
|
- if (get_transition_into(tmt, atw)) {
|
|
|
- _tex_mat = tmt->get_matrix();
|
|
|
- }
|
|
|
-
|
|
|
- // Check for color matrix.
|
|
|
- const ColorMatrixTransition *cmt;
|
|
|
- if (get_transition_into(cmt, atw)) {
|
|
|
- _color_mat = cmt->get_matrix();
|
|
|
- }
|
|
|
-
|
|
|
- // Check for alpha scale/offset.
|
|
|
- const AlphaTransformTransition *att;
|
|
|
- if (get_transition_into(att, atw)) {
|
|
|
- _alpha_scale = att->get_scale();
|
|
|
- _alpha_offset = att->get_offset();
|
|
|
- }
|
|
|
-
|
|
|
- // Check for texture.
|
|
|
- const TextureTransition *txt;
|
|
|
- if (get_transition_into(txt, atw)) {
|
|
|
- if (txt->is_on()) {
|
|
|
- _tex = txt->get_texture();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Check for bface.
|
|
|
- const CullFaceTransition *cft;
|
|
|
- if (get_transition_into(cft, atw)) {
|
|
|
- if (cft->get_mode() == CullFaceProperty::M_cull_none) {
|
|
|
- _bface = true;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::apply_vertex
|
|
|
-// Access: Public
|
|
|
-// Description: Applies the indicated vertex coordinate to the given
|
|
|
-// EggVertex, after modifying it according to the
|
|
|
-// current state.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-apply_vertex(EggVertex &egg_vert, const Vertexf &vertex) {
|
|
|
- LPoint3f transformed = vertex * _mat;
|
|
|
- egg_vert.set_pos(LCAST(double, transformed));
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::apply_normal
|
|
|
-// Access: Public
|
|
|
-// Description: Applies the indicated vertex normal to the given
|
|
|
-// EggVertex, after modifying it according to the
|
|
|
-// current state.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-apply_normal(EggVertex &egg_vert, const Normalf &normal) {
|
|
|
- LPoint3f transformed = normal * _mat;
|
|
|
- egg_vert.set_normal(LCAST(double, transformed));
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::apply_uv
|
|
|
-// Access: Public
|
|
|
-// Description: Applies the indicated vertex UV to the given
|
|
|
-// EggVertex, after modifying it according to the
|
|
|
-// current state.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-apply_uv(EggVertex &egg_vert, const TexCoordf &uv) {
|
|
|
- LVecBase4f v4(uv[0], uv[1], 0.0, 1.0);
|
|
|
- v4 = v4 * _tex_mat;
|
|
|
- egg_vert.set_uv(LCAST(double, uv));
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::apply_color
|
|
|
-// Access: Public
|
|
|
-// Description: Applies the indicated vertex color to the given
|
|
|
-// EggVertex, after modifying it according to the
|
|
|
-// current state.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-apply_color(EggVertex &egg_vert, const Colorf &color) {
|
|
|
- LPoint3f temp(color[0], color[1], color[2]);
|
|
|
- temp = temp * _color_mat;
|
|
|
- float alpha = (color[3] * _alpha_scale) +
|
|
|
- _alpha_offset;
|
|
|
-
|
|
|
- Colorf transformed(temp[0], temp[1], temp[2], alpha);
|
|
|
- egg_vert.set_color(transformed);
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::GeomState::apply_prim
|
|
|
-// Access: Public
|
|
|
-// Description: Applies generic, non-vertex-specific properties to
|
|
|
-// the primitive.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::GeomState::
|
|
|
-apply_prim(EggPrimitive *egg_prim) {
|
|
|
- if (_bface) {
|
|
|
- egg_prim->set_bface_flag(true);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: BamToEgg::Constructor
|
|
|
// Access: Public
|
|
|
@@ -189,9 +54,8 @@ BamToEgg::
|
|
|
BamToEgg() :
|
|
|
SomethingToEgg("Bam", ".bam")
|
|
|
{
|
|
|
- add_texture_path_options();
|
|
|
- add_rel_dir_options();
|
|
|
- add_search_path_options(true);
|
|
|
+ add_path_replace_options();
|
|
|
+ add_path_store_options();
|
|
|
|
|
|
set_program_description
|
|
|
("This program converts native Panda Bam files to egg. The conversion "
|
|
|
@@ -241,10 +105,11 @@ run() {
|
|
|
_vpool = new EggVertexPool("vpool");
|
|
|
_data.add_child(_vpool);
|
|
|
|
|
|
- if (objects.size() == 1 && objects[0]->is_of_type(Node::get_class_type())) {
|
|
|
- Node *node = DCAST(Node, objects[0]);
|
|
|
- ArcChain chain(node);
|
|
|
- convert_node(node, chain, &_data);
|
|
|
+ if (objects.size() == 1 &&
|
|
|
+ objects[0]->is_of_type(PandaNode::get_class_type())) {
|
|
|
+ PandaNode *node = DCAST(PandaNode, objects[0]);
|
|
|
+ NodePath root(node);
|
|
|
+ convert_node(WorkingNodePath(root), &_data, false);
|
|
|
|
|
|
} else {
|
|
|
nout << "File does not contain a scene graph.\n";
|
|
|
@@ -267,25 +132,22 @@ run() {
|
|
|
// is.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void BamToEgg::
|
|
|
-convert_node(Node *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
- if (node->is_of_type(LODNode::get_class_type())) {
|
|
|
- convert_lod_node(DCAST(LODNode, node), chain, egg_parent);
|
|
|
+convert_node(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
|
|
|
+ bool has_decal) {
|
|
|
+ PandaNode *node = node_path.node();
|
|
|
+ if (node->is_geom_node()) {
|
|
|
+ convert_geom_node(DCAST(GeomNode, node), node_path, egg_parent, has_decal);
|
|
|
|
|
|
- } else if (node->is_of_type(GeomNode::get_class_type())) {
|
|
|
- convert_geom_node(DCAST(GeomNode, node), chain, egg_parent);
|
|
|
+ } else if (node->is_of_type(LODNode::get_class_type())) {
|
|
|
+ convert_lod_node(DCAST(LODNode, node), node_path, egg_parent, has_decal);
|
|
|
|
|
|
} else {
|
|
|
- // Just a generic node. See if it has a name, at least.
|
|
|
- string name;
|
|
|
- if (node->is_of_type(NamedNode::get_class_type())) {
|
|
|
- name = DCAST(NamedNode, node)->get_name();
|
|
|
- }
|
|
|
-
|
|
|
- EggGroup *egg_group = new EggGroup(name);
|
|
|
+ // Just a generic node.
|
|
|
+ EggGroup *egg_group = new EggGroup(node->get_name());
|
|
|
egg_parent->add_child(egg_group);
|
|
|
- apply_arc_properties(egg_group, chain);
|
|
|
+ apply_node_properties(egg_group, node);
|
|
|
|
|
|
- recurse_nodes(node, chain, egg_group);
|
|
|
+ recurse_nodes(node_path, egg_group, has_decal);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -296,29 +158,25 @@ convert_node(Node *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
// Egg constructs.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void BamToEgg::
|
|
|
-convert_lod_node(LODNode *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
+convert_lod_node(LODNode *node, const WorkingNodePath &node_path,
|
|
|
+ EggGroupNode *egg_parent, bool has_decal) {
|
|
|
// An LOD node gets converted to an ordinary EggGroup, but we apply
|
|
|
// the appropriate switch conditions to each of our children.
|
|
|
- string name = node->get_name();
|
|
|
-
|
|
|
- EggGroup *egg_group = new EggGroup(name);
|
|
|
+ EggGroup *egg_group = new EggGroup(node->get_name());
|
|
|
egg_parent->add_child(egg_group);
|
|
|
- apply_arc_properties(egg_group, chain);
|
|
|
+ apply_node_properties(egg_group, node);
|
|
|
|
|
|
- int num_children = node->get_num_children(RenderRelation::get_class_type());
|
|
|
+ int num_children = node->get_num_children();
|
|
|
int num_switches = node->get_num_switches();
|
|
|
|
|
|
num_children = min(num_children, num_switches);
|
|
|
|
|
|
for (int i = 0; i < num_children; i++) {
|
|
|
- NodeRelation *arc =
|
|
|
- node->get_child(RenderRelation::get_class_type(), i);
|
|
|
- ArcChain next_chain(chain);
|
|
|
- next_chain.push_back(arc);
|
|
|
+ PandaNode *child = node->get_child(i);
|
|
|
|
|
|
// Convert just this one node to an EggGroup.
|
|
|
PT(EggGroup) next_group = new EggGroup;
|
|
|
- convert_node(arc->get_child(), next_chain, next_group);
|
|
|
+ convert_node(WorkingNodePath(node_path, child), next_group, has_decal);
|
|
|
|
|
|
if (next_group->size() == 1) {
|
|
|
// If we have exactly one child, and that child is an EggGroup,
|
|
|
@@ -334,7 +192,7 @@ convert_lod_node(LODNode *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
// Now set up the switching properties appropriately.
|
|
|
float in = node->get_in(i);
|
|
|
float out = node->get_out(i);
|
|
|
- LPoint3f center = node->_lod._center;
|
|
|
+ LPoint3f center = node->get_center();
|
|
|
EggSwitchConditionDistance dist(in, out, LCAST(double, center));
|
|
|
next_group->set_lod(dist);
|
|
|
egg_group->add_child(next_group.p());
|
|
|
@@ -344,50 +202,57 @@ convert_lod_node(LODNode *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: BamToEgg::convert_geom_node
|
|
|
// Access: Private
|
|
|
-// Description:
|
|
|
+// Description: Converts a GeomNode to the corresponding egg
|
|
|
+// structures.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void BamToEgg::
|
|
|
-convert_geom_node(GeomNode *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
- bool parent_has_decal = false;
|
|
|
- if (egg_parent->is_of_type(EggGroup::get_class_type())) {
|
|
|
- EggGroup *pg = DCAST(EggGroup, egg_parent);
|
|
|
- parent_has_decal = pg->get_decal_flag();
|
|
|
+convert_geom_node(GeomNode *node, const WorkingNodePath &node_path,
|
|
|
+ EggGroupNode *egg_parent, bool has_decal) {
|
|
|
+ PT(EggGroup) egg_group = new EggGroup(node->get_name());
|
|
|
+ bool fancy_attributes = apply_node_properties(egg_group, node);
|
|
|
+
|
|
|
+ if (node->get_effects()->has_decal()) {
|
|
|
+ has_decal = true;
|
|
|
}
|
|
|
|
|
|
- PT(EggGroup) egg_group = new EggGroup(node->get_name());
|
|
|
- bool fancy_transitions = apply_arc_properties(egg_group, chain);
|
|
|
- if (fancy_transitions || parent_has_decal) {
|
|
|
- // If we have any fancy transitions on the arc, or if we're making
|
|
|
+ if (has_decal) {
|
|
|
+ egg_group->set_decal_flag(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fancy_attributes || has_decal) {
|
|
|
+ // If we have any fancy attributes on the node, or if we're making
|
|
|
// decal geometry, we have to make a special node to hold the
|
|
|
// geometry (normally it would just appear within its parent).
|
|
|
egg_parent->add_child(egg_group.p());
|
|
|
egg_parent = egg_group;
|
|
|
}
|
|
|
-
|
|
|
|
|
|
- // Get the state associated with this GeomNode.
|
|
|
- GeomState state;
|
|
|
- state.get_net_state(node, chain, egg_parent);
|
|
|
+ NodePath np = node_path.get_node_path();
|
|
|
+ CPT(RenderState) net_state = np.get_net_state();
|
|
|
+ CPT(TransformState) net_transform = np.get_net_transform();
|
|
|
+ LMatrix4f net_mat = net_transform->get_mat();
|
|
|
+ LMatrix4f inv = LCAST(float, egg_parent->get_vertex_frame_inv());
|
|
|
+ net_mat = net_mat * inv;
|
|
|
|
|
|
// Now get out all the various kinds of geometry.
|
|
|
int num_geoms = node->get_num_geoms();
|
|
|
for (int i = 0; i < num_geoms; i++) {
|
|
|
- dDrawable *drawable = node->get_geom(i);
|
|
|
- if (drawable->is_of_type(Geom::get_class_type())) {
|
|
|
- // Explode the Geom before we try to deal with it. That way, we
|
|
|
- // don't have to know about tristrips or whatnot.
|
|
|
- Geom *geom = DCAST(Geom, drawable);
|
|
|
- PT(Geom) exploded = geom->explode();
|
|
|
-
|
|
|
- // Now determine what kind of Geom we've got. Chances are good
|
|
|
- // it's triangles.
|
|
|
- if (exploded->is_of_type(GeomTri::get_class_type())) {
|
|
|
- convert_geom_tri(DCAST(GeomTri, exploded), state, egg_parent);
|
|
|
- }
|
|
|
+ CPT(RenderState) geom_state = net_state->compose(node->get_geom_state(i));
|
|
|
+
|
|
|
+ Geom *geom = node->get_geom(i);
|
|
|
+ // Explode the Geom before we try to deal with it. That way, we
|
|
|
+ // don't have to know about tristrips or whatnot.
|
|
|
+ PT(Geom) exploded = geom->explode();
|
|
|
+
|
|
|
+ // Now determine what kind of Geom we've got. Chances are good
|
|
|
+ // it's triangles.
|
|
|
+ if (exploded->is_of_type(GeomTri::get_class_type())) {
|
|
|
+ convert_geom_tri(DCAST(GeomTri, exploded), geom_state, net_mat,
|
|
|
+ egg_parent);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- recurse_nodes(node, chain, egg_parent);
|
|
|
+ recurse_nodes(node_path, egg_parent, has_decal);
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
@@ -396,7 +261,8 @@ convert_geom_node(GeomNode *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
// Description:
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void BamToEgg::
|
|
|
-convert_geom_tri(GeomTri *geom, BamToEgg::GeomState &state, EggGroupNode *egg_parent) {
|
|
|
+convert_geom_tri(GeomTri *geom, const RenderState *net_state,
|
|
|
+ const LMatrix4f &net_mat, EggGroupNode *egg_parent) {
|
|
|
int nprims = geom->get_num_prims();
|
|
|
Geom::VertexIterator vi = geom->make_vertex_iterator();
|
|
|
Geom::NormalIterator ni = geom->make_normal_iterator();
|
|
|
@@ -408,70 +274,113 @@ convert_geom_tri(GeomTri *geom, BamToEgg::GeomState &state, EggGroupNode *egg_pa
|
|
|
GeomBindType tb = geom->get_binding(G_TEXCOORD);
|
|
|
GeomBindType cb = geom->get_binding(G_COLOR);
|
|
|
|
|
|
- Vertexf vertex;
|
|
|
+ // Check for a color scale.
|
|
|
+ LVecBase4f color_scale(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
+ const RenderAttrib *color_scale_attrib = net_state->get_attrib(ColorScaleAttrib::get_class_type());
|
|
|
+ if (color_scale_attrib != (const RenderAttrib *)NULL) {
|
|
|
+ const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, color_scale_attrib);
|
|
|
+ color_scale = csa->get_scale();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check for a color override.
|
|
|
+ bool has_color_override = false;
|
|
|
+ bool has_color_off = false;
|
|
|
+ Colorf color_override;
|
|
|
+ const RenderAttrib *color_attrib = net_state->get_attrib(ColorAttrib::get_class_type());
|
|
|
+ if (color_attrib != (const RenderAttrib *)NULL) {
|
|
|
+ const ColorAttrib *ca = DCAST(ColorAttrib, color_attrib);
|
|
|
+ if (ca->get_color_type() == ColorAttrib::T_flat) {
|
|
|
+ has_color_override = true;
|
|
|
+ color_override = ca->get_color();
|
|
|
+ color_override.set(color_override[0] * color_scale[0],
|
|
|
+ color_override[1] * color_scale[1],
|
|
|
+ color_override[2] * color_scale[2],
|
|
|
+ color_override[3] * color_scale[3]);
|
|
|
+
|
|
|
+ } else if (ca->get_color_type() == ColorAttrib::T_off) {
|
|
|
+ has_color_off = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check for a texture.
|
|
|
+ EggTexture *egg_tex = (EggTexture *)NULL;
|
|
|
+ const RenderAttrib *tex_attrib = net_state->get_attrib(TextureAttrib::get_class_type());
|
|
|
+ if (tex_attrib != (const RenderAttrib *)NULL) {
|
|
|
+ const TextureAttrib *ta = DCAST(TextureAttrib, tex_attrib);
|
|
|
+ egg_tex = get_egg_texture(ta->get_texture());
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check the backface flag.
|
|
|
+ bool bface = false;
|
|
|
+ const RenderAttrib *cf_attrib = net_state->get_attrib(CullFaceAttrib::get_class_type());
|
|
|
+ if (cf_attrib != (const RenderAttrib *)NULL) {
|
|
|
+ const CullFaceAttrib *cfa = DCAST(CullFaceAttrib, cf_attrib);
|
|
|
+ if (cfa->get_mode() == CullFaceAttrib::M_cull_none) {
|
|
|
+ bface = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
Normalf normal;
|
|
|
- TexCoordf uv;
|
|
|
Colorf color;
|
|
|
|
|
|
// Get overall properties.
|
|
|
- if (vb == G_OVERALL) {
|
|
|
- vertex = geom->get_next_vertex(vi);
|
|
|
- }
|
|
|
if (nb == G_OVERALL) {
|
|
|
normal = geom->get_next_normal(ni);
|
|
|
}
|
|
|
- if (tb == G_OVERALL) {
|
|
|
- uv = geom->get_next_texcoord(ti);
|
|
|
- }
|
|
|
if (cb == G_OVERALL) {
|
|
|
color = geom->get_next_color(ci);
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < nprims; i++) {
|
|
|
// Get per-prim properties.
|
|
|
- if (vb == G_PER_PRIM) {
|
|
|
- vertex = geom->get_next_vertex(vi);
|
|
|
- }
|
|
|
if (nb == G_PER_PRIM) {
|
|
|
normal = geom->get_next_normal(ni);
|
|
|
}
|
|
|
- if (tb == G_PER_PRIM) {
|
|
|
- uv = geom->get_next_texcoord(ti);
|
|
|
- }
|
|
|
if (cb == G_PER_PRIM) {
|
|
|
color = geom->get_next_color(ci);
|
|
|
}
|
|
|
|
|
|
EggPolygon *egg_poly = new EggPolygon;
|
|
|
egg_parent->add_child(egg_poly);
|
|
|
- apply_texture(egg_poly, state._tex);
|
|
|
- state.apply_prim(egg_poly);
|
|
|
+ if (egg_tex != (EggTexture *)NULL) {
|
|
|
+ egg_poly->set_texture(egg_tex);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bface) {
|
|
|
+ egg_poly->set_bface_flag(true);
|
|
|
+ }
|
|
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
+ EggVertex egg_vert;
|
|
|
+
|
|
|
// Get per-vertex properties.
|
|
|
if (vb == G_PER_VERTEX) {
|
|
|
- vertex = geom->get_next_vertex(vi);
|
|
|
+ Vertexf vertex = geom->get_next_vertex(vi);
|
|
|
+ egg_vert.set_pos(LCAST(double, vertex * net_mat));
|
|
|
}
|
|
|
if (nb == G_PER_VERTEX) {
|
|
|
- normal = geom->get_next_normal(ni);
|
|
|
+ normal = geom->get_next_normal(ni) * net_mat;
|
|
|
}
|
|
|
if (tb == G_PER_VERTEX) {
|
|
|
- uv = geom->get_next_texcoord(ti);
|
|
|
+ TexCoordf uv = geom->get_next_texcoord(ti);
|
|
|
+ egg_vert.set_uv(LCAST(double, uv));
|
|
|
}
|
|
|
if (cb == G_PER_VERTEX) {
|
|
|
color = geom->get_next_color(ci);
|
|
|
}
|
|
|
|
|
|
- EggVertex egg_vert;
|
|
|
- state.apply_vertex(egg_vert, vertex);
|
|
|
if (nb != G_OFF) {
|
|
|
- state.apply_normal(egg_vert, normal);
|
|
|
- }
|
|
|
- if (tb != G_OFF) {
|
|
|
- state.apply_uv(egg_vert, uv);
|
|
|
+ egg_vert.set_normal(LCAST(double, normal * net_mat));
|
|
|
}
|
|
|
- if (cb != G_OFF) {
|
|
|
- state.apply_color(egg_vert, color);
|
|
|
+
|
|
|
+ if (has_color_override) {
|
|
|
+ egg_vert.set_color(color_override);
|
|
|
+
|
|
|
+ } else if (!has_color_off && cb != G_OFF) {
|
|
|
+ egg_vert.set_color(Colorf(color[0] * color_scale[0],
|
|
|
+ color[1] * color_scale[1],
|
|
|
+ color[2] * color_scale[2],
|
|
|
+ color[3] * color_scale[3]));
|
|
|
}
|
|
|
|
|
|
EggVertex *new_egg_vert = _vpool->create_unique_vertex(egg_vert);
|
|
|
@@ -480,48 +389,106 @@ convert_geom_tri(GeomTri *geom, BamToEgg::GeomState &state, EggGroupNode *egg_pa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: BamToEgg::recurse_nodes
|
|
|
// Access: Private
|
|
|
// Description: Converts all the children of the indicated node.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void BamToEgg::
|
|
|
-recurse_nodes(Node *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
- int num_children = node->get_num_children(RenderRelation::get_class_type());
|
|
|
-
|
|
|
+recurse_nodes(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
|
|
|
+ bool has_decal) {
|
|
|
+ PandaNode *node = node_path.node();
|
|
|
+ int num_children = node->get_num_children();
|
|
|
+
|
|
|
for (int i = 0; i < num_children; i++) {
|
|
|
- NodeRelation *arc =
|
|
|
- node->get_child(RenderRelation::get_class_type(), i);
|
|
|
- ArcChain next_chain(chain);
|
|
|
- next_chain.push_back(arc);
|
|
|
- convert_node(arc->get_child(), next_chain, egg_parent);
|
|
|
+ PandaNode *child = node->get_child(i);
|
|
|
+ convert_node(WorkingNodePath(node_path, child), egg_parent, has_decal);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::apply_texture
|
|
|
+// Function: BamToEgg::apply_node_properties
|
|
|
// Access: Public
|
|
|
-// Description: Applies the texture, if any, to the indicated
|
|
|
-// EggPrimitive.
|
|
|
+// Description: Applies any special properties that might be stored
|
|
|
+// on the node, like billboarding. Returns true if any
|
|
|
+// were applied, false otherwise.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-void BamToEgg::
|
|
|
-apply_texture(EggPrimitive *egg_prim, Texture *tex) {
|
|
|
+bool BamToEgg::
|
|
|
+apply_node_properties(EggGroup *egg_group, PandaNode *node) {
|
|
|
+ bool any_applied = false;
|
|
|
+
|
|
|
+ if (node->get_draw_mask().is_zero()) {
|
|
|
+ // This node is hidden. We'll go ahead and convert it, but we'll
|
|
|
+ // put in the "backstage" flag to mean it's not real geometry.
|
|
|
+ egg_group->add_object_type("backstage");
|
|
|
+ }
|
|
|
+
|
|
|
+ const RenderEffects *effects = node->get_effects();
|
|
|
+ const BillboardEffect *bbe = effects->get_billboard();
|
|
|
+ if (bbe != (const BillboardEffect *)NULL) {
|
|
|
+ if (bbe->get_axial_rotate()) {
|
|
|
+ egg_group->set_billboard_type(EggGroup::BT_axis);
|
|
|
+ any_applied = true;
|
|
|
+
|
|
|
+ } else if (bbe->get_eye_relative()) {
|
|
|
+ egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
|
|
|
+ any_applied = true;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ egg_group->set_billboard_type(EggGroup::BT_point_world_relative);
|
|
|
+ any_applied = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const TransformState *transform = node->get_transform();
|
|
|
+ if (!transform->is_identity()) {
|
|
|
+ if (transform->has_components()) {
|
|
|
+ // If the transform can be represented componentwise, we prefer
|
|
|
+ // storing it that way in the egg file.
|
|
|
+ const LVecBase3f &scale = transform->get_scale();
|
|
|
+ const LQuaternionf &quat = transform->get_quat();
|
|
|
+ const LVecBase3f &pos = transform->get_pos();
|
|
|
+ if (!scale.almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
|
|
|
+ egg_group->add_scale(LCAST(double, scale));
|
|
|
+ }
|
|
|
+ if (!quat.is_identity()) {
|
|
|
+ egg_group->add_rotate(LCAST(double, quat));
|
|
|
+ }
|
|
|
+ if (!pos.almost_equal(LVecBase3f::zero())) {
|
|
|
+ egg_group->add_translate(LCAST(double, pos));
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (transform->has_mat()) {
|
|
|
+ // Otherwise, we store the raw matrix.
|
|
|
+ const LMatrix4f &mat = transform->get_mat();
|
|
|
+ egg_group->set_transform(LCAST(double, mat));
|
|
|
+ }
|
|
|
+ any_applied = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return any_applied;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::get_egg_texture
|
|
|
+// Access: Public
|
|
|
+// Description: Returns an EggTexture pointer that corresponds to the
|
|
|
+// indicated Texture.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+EggTexture *BamToEgg::
|
|
|
+get_egg_texture(Texture *tex) {
|
|
|
if (tex != (Texture *)NULL) {
|
|
|
if (tex->has_filename()) {
|
|
|
- Filename filename = SomethingToEggConverter::convert_path
|
|
|
- (tex->get_filename(), get_texture_path(), _make_rel_dir,
|
|
|
- _texture_path_convert);
|
|
|
-
|
|
|
- EggTexture temp("", filename);
|
|
|
+ Filename filename = tex->get_filename();
|
|
|
+ EggTexture temp(filename.get_basename_wo_extension(), filename);
|
|
|
if (tex->has_alpha_filename()) {
|
|
|
- Filename alpha = SomethingToEggConverter::convert_path
|
|
|
- (tex->get_alpha_filename(), get_texture_path(), _make_rel_dir,
|
|
|
- _texture_path_convert);
|
|
|
- temp.set_alpha_file(alpha);
|
|
|
+ Filename alpha = tex->get_alpha_filename();
|
|
|
+ temp.set_alpha_filename(alpha);
|
|
|
}
|
|
|
|
|
|
switch (tex->get_minfilter()) {
|
|
|
+ case Texture::FT_invalid:
|
|
|
+ break;
|
|
|
case Texture::FT_nearest:
|
|
|
temp.set_minfilter(EggTexture::FT_nearest);
|
|
|
break;
|
|
|
@@ -560,6 +527,11 @@ apply_texture(EggPrimitive *egg_prim, Texture *tex) {
|
|
|
case Texture::WM_repeat:
|
|
|
temp.set_wrap_u(EggTexture::WM_repeat);
|
|
|
break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ // There are some new wrap options on Texture that aren't yet
|
|
|
+ // supported in egg.
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
switch (tex->get_wrapv()) {
|
|
|
@@ -569,6 +541,11 @@ apply_texture(EggPrimitive *egg_prim, Texture *tex) {
|
|
|
case Texture::WM_repeat:
|
|
|
temp.set_wrap_v(EggTexture::WM_repeat);
|
|
|
break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ // There are some new wrap options on Texture that aren't yet
|
|
|
+ // supported in egg.
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
PixelBuffer *pbuf = tex->get_ram_image();
|
|
|
@@ -633,61 +610,161 @@ apply_texture(EggPrimitive *egg_prim, Texture *tex) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- EggTexture *egg_tex =
|
|
|
- _textures.create_unique_texture(temp, ~EggTexture::E_tref_name);
|
|
|
- egg_prim->set_texture(egg_tex);
|
|
|
+ return _textures.create_unique_texture(temp, ~EggTexture::E_tref_name);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
+#if 0
|
|
|
+
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: BamToEgg::apply_arc_properties
|
|
|
+// Function: BamToEgg::GeomState::Constructor
|
|
|
// Access: Public
|
|
|
-// Description: Applies any special properties that might be stored
|
|
|
-// on the arc, like billboarding. Returns true if any
|
|
|
-// were applied, false otherwise.
|
|
|
+// Description:
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-bool BamToEgg::
|
|
|
-apply_arc_properties(EggGroup *egg_group, ArcChain &chain) {
|
|
|
- if (!chain.has_arcs()) {
|
|
|
- return false;
|
|
|
+BamToEgg::GeomState::
|
|
|
+GeomState() {
|
|
|
+ _mat = LMatrix4f::ident_mat();
|
|
|
+ _tex_mat = LMatrix4f::ident_mat();
|
|
|
+ _color_mat = LMatrix4f::ident_mat();
|
|
|
+ _alpha_scale = 1.0;
|
|
|
+ _alpha_offset = 0.0;
|
|
|
+ _tex = (Texture *)NULL;
|
|
|
+ _bface = false;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::get_net_state
|
|
|
+// Access: Public
|
|
|
+// Description: Gets the accumulated state of the indicated node (and
|
|
|
+// its corresponding ArcChain) into the GeomState.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+get_net_state(Node *node, ArcChain &chain, EggGroupNode *egg_parent) {
|
|
|
+ AllTransitionsWrapper atw;
|
|
|
+
|
|
|
+ wrt(node, chain.begin(), chain.end(),
|
|
|
+ (Node *)NULL,
|
|
|
+ atw, RenderRelation::get_class_type());
|
|
|
+
|
|
|
+ // Check for transform space.
|
|
|
+ const TransformTransition *tt;
|
|
|
+ if (get_transition_into(tt, atw)) {
|
|
|
+ _mat = tt->get_matrix();
|
|
|
+ LMatrix4f inv = LCAST(float, egg_parent->get_vertex_frame_inv());
|
|
|
+ _mat = _mat * inv;
|
|
|
}
|
|
|
- NodeRelation *arc = chain.back();
|
|
|
- bool any_applied = false;
|
|
|
|
|
|
- BillboardTransition *bt;
|
|
|
- if (get_transition_into(bt, arc)) {
|
|
|
- if (bt->get_axial_rotate()) {
|
|
|
- egg_group->set_billboard_type(EggGroup::BT_axis);
|
|
|
- any_applied = true;
|
|
|
+ // Check for texture matrix.
|
|
|
+ const TexMatrixTransition *tmt;
|
|
|
+ if (get_transition_into(tmt, atw)) {
|
|
|
+ _tex_mat = tmt->get_matrix();
|
|
|
+ }
|
|
|
|
|
|
- } else if (bt->get_eye_relative()) {
|
|
|
- egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
|
|
|
- any_applied = true;
|
|
|
+ // Check for color matrix.
|
|
|
+ const ColorMatrixTransition *cmt;
|
|
|
+ if (get_transition_into(cmt, atw)) {
|
|
|
+ _color_mat = cmt->get_matrix();
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
- egg_group->set_billboard_type(EggGroup::BT_point_world_relative);
|
|
|
- any_applied = true;
|
|
|
- }
|
|
|
+ // Check for alpha scale/offset.
|
|
|
+ const AlphaTransformTransition *att;
|
|
|
+ if (get_transition_into(att, atw)) {
|
|
|
+ _alpha_scale = att->get_scale();
|
|
|
+ _alpha_offset = att->get_offset();
|
|
|
}
|
|
|
|
|
|
- const TransformTransition *tt;
|
|
|
- if (get_transition_into(tt, arc)) {
|
|
|
- LMatrix4f mat = tt->get_matrix();
|
|
|
- egg_group->set_transform(LCAST(double, mat));
|
|
|
- any_applied = true;
|
|
|
+ // Check for texture.
|
|
|
+ const TextureTransition *txt;
|
|
|
+ if (get_transition_into(txt, atw)) {
|
|
|
+ if (txt->is_on()) {
|
|
|
+ _tex = txt->get_texture();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- const DecalTransition *dt;
|
|
|
- if (get_transition_into(dt, arc)) {
|
|
|
- if (dt->is_on()) {
|
|
|
- egg_group->set_decal_flag(true);
|
|
|
- any_applied = true;
|
|
|
+ // Check for bface.
|
|
|
+ const CullFaceTransition *cft;
|
|
|
+ if (get_transition_into(cft, atw)) {
|
|
|
+ if (cft->get_mode() == CullFaceProperty::M_cull_none) {
|
|
|
+ _bface = true;
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- return any_applied;
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::apply_vertex
|
|
|
+// Access: Public
|
|
|
+// Description: Applies the indicated vertex coordinate to the given
|
|
|
+// EggVertex, after modifying it according to the
|
|
|
+// current state.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+apply_vertex(EggVertex &egg_vert, const Vertexf &vertex) {
|
|
|
+ LPoint3f transformed = vertex * _mat;
|
|
|
+ egg_vert.set_pos(LCAST(double, transformed));
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::apply_normal
|
|
|
+// Access: Public
|
|
|
+// Description: Applies the indicated vertex normal to the given
|
|
|
+// EggVertex, after modifying it according to the
|
|
|
+// current state.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+apply_normal(EggVertex &egg_vert, const Normalf &normal) {
|
|
|
+ LPoint3f transformed = normal * _mat;
|
|
|
+ egg_vert.set_normal(LCAST(double, transformed));
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::apply_uv
|
|
|
+// Access: Public
|
|
|
+// Description: Applies the indicated vertex UV to the given
|
|
|
+// EggVertex, after modifying it according to the
|
|
|
+// current state.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+apply_uv(EggVertex &egg_vert, const TexCoordf &uv) {
|
|
|
+ LVecBase4f v4(uv[0], uv[1], 0.0, 1.0);
|
|
|
+ v4 = v4 * _tex_mat;
|
|
|
+ egg_vert.set_uv(LCAST(double, uv));
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::apply_color
|
|
|
+// Access: Public
|
|
|
+// Description: Applies the indicated vertex color to the given
|
|
|
+// EggVertex, after modifying it according to the
|
|
|
+// current state.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+apply_color(EggVertex &egg_vert, const Colorf &color) {
|
|
|
+ LPoint3f temp(color[0], color[1], color[2]);
|
|
|
+ temp = temp * _color_mat;
|
|
|
+ float alpha = (color[3] * _alpha_scale) +
|
|
|
+ _alpha_offset;
|
|
|
+
|
|
|
+ Colorf transformed(temp[0], temp[1], temp[2], alpha);
|
|
|
+ egg_vert.set_color(transformed);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: BamToEgg::GeomState::apply_prim
|
|
|
+// Access: Public
|
|
|
+// Description: Applies generic, non-vertex-specific properties to
|
|
|
+// the primitive.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void BamToEgg::GeomState::
|
|
|
+apply_prim(EggPrimitive *egg_prim) {
|
|
|
+ if (_bface) {
|
|
|
+ egg_prim->set_bface_flag(true);
|
|
|
+ }
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|