diff --git a/panda/src/egg/eggLine.cxx b/panda/src/egg/eggLine.cxx index 4da9b87d7d..fca1efd7f1 100644 --- a/panda/src/egg/eggLine.cxx +++ b/panda/src/egg/eggLine.cxx @@ -17,7 +17,6 @@ TypeHandle EggLine::_type_handle; - /** * */ @@ -26,6 +25,14 @@ EggLine:: clear(); } +/** + * Makes a copy of this object. + */ +EggLine *EggLine:: +make_copy() const { + return new EggLine(*this); +} + /** * Writes the point to the indicated output stream in Egg format. */ diff --git a/panda/src/egg/eggLine.h b/panda/src/egg/eggLine.h index ce036c40f3..059dfa7648 100644 --- a/panda/src/egg/eggLine.h +++ b/panda/src/egg/eggLine.h @@ -29,6 +29,8 @@ PUBLISHED: INLINE EggLine &operator = (const EggLine ©); virtual ~EggLine(); + virtual EggLine *make_copy() const OVERRIDE; + virtual void write(ostream &out, int indent_level) const; INLINE bool has_thick() const; diff --git a/panda/src/egg/eggNurbsCurve.cxx b/panda/src/egg/eggNurbsCurve.cxx index f00528f0f0..79b1d5011b 100644 --- a/panda/src/egg/eggNurbsCurve.cxx +++ b/panda/src/egg/eggNurbsCurve.cxx @@ -17,6 +17,14 @@ TypeHandle EggNurbsCurve::_type_handle; +/** + * Makes a copy of this object. + */ +EggNurbsCurve *EggNurbsCurve:: +make_copy() const { + return new EggNurbsCurve(*this); +} + /** * Prepares a new curve definition with the indicated order and number of * knots. This also implies a particular number of vertices as well (the diff --git a/panda/src/egg/eggNurbsCurve.h b/panda/src/egg/eggNurbsCurve.h index 5eb8a054c8..9797a12ea8 100644 --- a/panda/src/egg/eggNurbsCurve.h +++ b/panda/src/egg/eggNurbsCurve.h @@ -29,6 +29,8 @@ PUBLISHED: INLINE EggNurbsCurve(const EggNurbsCurve ©); INLINE EggNurbsCurve &operator = (const EggNurbsCurve ©); + virtual EggNurbsCurve *make_copy() const OVERRIDE; + void setup(int order, int num_knots); INLINE void set_order(int order); diff --git a/panda/src/egg/eggNurbsSurface.cxx b/panda/src/egg/eggNurbsSurface.cxx index a5bd29cc78..c89ebfe157 100644 --- a/panda/src/egg/eggNurbsSurface.cxx +++ b/panda/src/egg/eggNurbsSurface.cxx @@ -17,6 +17,14 @@ TypeHandle EggNurbsSurface::_type_handle; +/** + * Makes a copy of this object. + */ +EggNurbsSurface *EggNurbsSurface:: +make_copy() const { + return new EggNurbsSurface(*this); +} + /** * Prepares a new surface definition with the indicated order and number of * knots in each dimension. This also implies a particular number of vertices diff --git a/panda/src/egg/eggNurbsSurface.h b/panda/src/egg/eggNurbsSurface.h index 35d5daba88..8e09d43fbd 100644 --- a/panda/src/egg/eggNurbsSurface.h +++ b/panda/src/egg/eggNurbsSurface.h @@ -36,6 +36,8 @@ PUBLISHED: INLINE EggNurbsSurface(const EggNurbsSurface ©); INLINE EggNurbsSurface &operator = (const EggNurbsSurface ©); + virtual EggNurbsSurface *make_copy() const OVERRIDE; + void setup(int u_order, int v_order, int num_u_knots, int num_v_knots); diff --git a/panda/src/egg/eggPatch.cxx b/panda/src/egg/eggPatch.cxx index 274217d0c2..0bed947622 100644 --- a/panda/src/egg/eggPatch.cxx +++ b/panda/src/egg/eggPatch.cxx @@ -21,6 +21,13 @@ TypeHandle EggPatch::_type_handle; +/** + * Makes a copy of this object. + */ +EggPatch *EggPatch:: +make_copy() const { + return new EggPatch(*this); +} /** * Writes the patch to the indicated output stream in Egg format. diff --git a/panda/src/egg/eggPatch.h b/panda/src/egg/eggPatch.h index d7a0989aef..63cfc61353 100644 --- a/panda/src/egg/eggPatch.h +++ b/panda/src/egg/eggPatch.h @@ -28,6 +28,8 @@ PUBLISHED: INLINE EggPatch(const EggPatch ©); INLINE EggPatch &operator = (const EggPatch ©); + virtual EggPatch *make_copy() const OVERRIDE; + virtual void write(ostream &out, int indent_level) const; public: diff --git a/panda/src/egg/eggPoint.cxx b/panda/src/egg/eggPoint.cxx index 95eef093ea..a344ee59cd 100644 --- a/panda/src/egg/eggPoint.cxx +++ b/panda/src/egg/eggPoint.cxx @@ -17,6 +17,13 @@ TypeHandle EggPoint::_type_handle; +/** + * Makes a copy of this object. + */ +EggPoint *EggPoint:: +make_copy() const { + return new EggPoint(*this); +} /** * Cleans up modeling errors in whatever context this makes sense. For diff --git a/panda/src/egg/eggPoint.h b/panda/src/egg/eggPoint.h index 74edd1b04d..ae7d7e1d34 100644 --- a/panda/src/egg/eggPoint.h +++ b/panda/src/egg/eggPoint.h @@ -28,6 +28,8 @@ PUBLISHED: INLINE EggPoint(const EggPoint ©); INLINE EggPoint &operator = (const EggPoint ©); + virtual EggPoint *make_copy() const OVERRIDE; + INLINE bool has_thick() const; INLINE double get_thick() const; INLINE void set_thick(double thick); diff --git a/panda/src/egg/eggPolygon.cxx b/panda/src/egg/eggPolygon.cxx index e10252c2ae..2d6a3378c7 100644 --- a/panda/src/egg/eggPolygon.cxx +++ b/panda/src/egg/eggPolygon.cxx @@ -21,6 +21,13 @@ TypeHandle EggPolygon::_type_handle; +/** + * Makes a copy of this object. + */ +EggPolygon *EggPolygon:: +make_copy() const { + return new EggPolygon(*this); +} /** * Cleans up modeling errors in whatever context this makes sense. For diff --git a/panda/src/egg/eggPolygon.h b/panda/src/egg/eggPolygon.h index 7c0298d9bd..a549af3bf7 100644 --- a/panda/src/egg/eggPolygon.h +++ b/panda/src/egg/eggPolygon.h @@ -27,6 +27,8 @@ PUBLISHED: INLINE EggPolygon(const EggPolygon ©); INLINE EggPolygon &operator = (const EggPolygon ©); + virtual EggPolygon *make_copy() const OVERRIDE; + virtual bool cleanup(); bool calculate_normal(LNormald &result, CoordinateSystem cs = CS_default) const; diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h index 4e8672249e..905e049596 100644 --- a/panda/src/egg/eggPrimitive.h +++ b/panda/src/egg/eggPrimitive.h @@ -72,6 +72,8 @@ PUBLISHED: INLINE EggPrimitive &operator = (const EggPrimitive ©); INLINE ~EggPrimitive(); + virtual EggPrimitive *make_copy() const=0; + virtual EggRenderMode *determine_alpha_mode(); virtual EggRenderMode *determine_depth_write_mode(); virtual EggRenderMode *determine_depth_test_mode(); diff --git a/panda/src/egg/eggTriangleFan.cxx b/panda/src/egg/eggTriangleFan.cxx index d71ad75fed..30d441286a 100644 --- a/panda/src/egg/eggTriangleFan.cxx +++ b/panda/src/egg/eggTriangleFan.cxx @@ -18,7 +18,6 @@ TypeHandle EggTriangleFan::_type_handle; - /** * */ @@ -27,6 +26,14 @@ EggTriangleFan:: clear(); } +/** + * Makes a copy of this object. + */ +EggTriangleFan *EggTriangleFan:: +make_copy() const { + return new EggTriangleFan(*this); +} + /** * Writes the triangle fan to the indicated output stream in Egg format. */ diff --git a/panda/src/egg/eggTriangleFan.h b/panda/src/egg/eggTriangleFan.h index 1cf6e1edf9..0a5e3f1e35 100644 --- a/panda/src/egg/eggTriangleFan.h +++ b/panda/src/egg/eggTriangleFan.h @@ -29,6 +29,8 @@ PUBLISHED: INLINE EggTriangleFan &operator = (const EggTriangleFan ©); virtual ~EggTriangleFan(); + virtual EggTriangleFan *make_copy() const OVERRIDE; + virtual void write(ostream &out, int indent_level) const; virtual void apply_first_attribute(); diff --git a/panda/src/egg/eggTriangleStrip.cxx b/panda/src/egg/eggTriangleStrip.cxx index 41bd5c4668..5882471c9e 100644 --- a/panda/src/egg/eggTriangleStrip.cxx +++ b/panda/src/egg/eggTriangleStrip.cxx @@ -18,7 +18,6 @@ TypeHandle EggTriangleStrip::_type_handle; - /** * */ @@ -27,6 +26,14 @@ EggTriangleStrip:: clear(); } +/** + * Makes a copy of this object. + */ +EggTriangleStrip *EggTriangleStrip:: +make_copy() const { + return new EggTriangleStrip(*this); +} + /** * Writes the triangle strip to the indicated output stream in Egg format. */ diff --git a/panda/src/egg/eggTriangleStrip.h b/panda/src/egg/eggTriangleStrip.h index 1400aefbd9..202172d1cd 100644 --- a/panda/src/egg/eggTriangleStrip.h +++ b/panda/src/egg/eggTriangleStrip.h @@ -29,6 +29,8 @@ PUBLISHED: INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©); virtual ~EggTriangleStrip(); + virtual EggTriangleStrip *make_copy() const OVERRIDE; + virtual void write(ostream &out, int indent_level) const; protected: diff --git a/panda/src/egg2pg/eggSaver.cxx b/panda/src/egg2pg/eggSaver.cxx index 3ddddffe3f..97f564ae9b 100644 --- a/panda/src/egg2pg/eggSaver.cxx +++ b/panda/src/egg2pg/eggSaver.cxx @@ -23,8 +23,11 @@ #include "colorAttrib.h" #include "materialAttrib.h" #include "textureAttrib.h" +#include "cullBinAttrib.h" #include "cullFaceAttrib.h" #include "transparencyAttrib.h" +#include "depthTestAttrib.h" +#include "depthOffsetAttrib.h" #include "depthWriteAttrib.h" #include "lodNode.h" #include "switchNode.h" @@ -101,6 +104,26 @@ add_node(PandaNode *node) { _vpool = NULL; } +/** + * Adds the scene graph rooted at the indicated node (but without the node + * itself) to the accumulated egg data within this object. Call + * get_egg_data() to retrieve the result. + */ +void EggSaver:: +add_subgraph(PandaNode *root) { + _vpool = new EggVertexPool(root->get_name()); + _data->add_child(_vpool); + + NodePath root_path(root); + recurse_nodes(root_path, _data, false, NULL); + + // Remove the vertex pool if it has no vertices. + if (_vpool->empty()) { + _data->remove_child(_vpool); + } + _vpool = NULL; +} + /** * Converts the indicated node to the corresponding Egg constructs, by first * determining what kind of node it is. @@ -359,9 +382,12 @@ convert_character_node(Character *node, const WorkingNodePath &node_path, EggGroupNode *egg_parent, bool has_decal) { // A sequence node gets converted to an ordinary EggGroup, we only apply the - // appropriate switch attributes to turn it into a sequence + // appropriate switch attributes to turn it into a sequence. + // We have to use DT_structured since it is the only mode that preserves the + // node hierarchy, including LODNodes and CollisionNodes that may be under + // this Character node. EggGroup *egg_group = new EggGroup(node->get_name()); - egg_group->set_dart_type(EggGroup::DT_default); + egg_group->set_dart_type(EggGroup::DT_structured); egg_parent->add_child(egg_group); apply_node_properties(egg_group, node); @@ -611,7 +637,8 @@ convert_geom_node(GeomNode *node, const WorkingNodePath &node_path, // Now get out all the various kinds of geometry. int num_geoms = node->get_num_geoms(); for (int i = 0; i < num_geoms; ++i) { - CPT(RenderState) geom_state = net_state->compose(node->get_geom_state(i)); + CPT(RenderState) geom_state = node->get_geom_state(i); + CPT(RenderState) geom_net_state = net_state->compose(geom_state); const Geom *geom = node->get_geom(i); int num_primitives = geom->get_num_primitives(); @@ -620,7 +647,7 @@ convert_geom_node(GeomNode *node, const WorkingNodePath &node_path, CPT(GeomPrimitive) simple = primitive->decompose(); CPT(GeomVertexData) vdata = geom->get_vertex_data(); // vdata = vdata->animate_vertices(true, Thread::get_current_thread()); - convert_primitive(vdata, simple, geom_state, + convert_primitive(vdata, simple, geom_state, geom_net_state, net_mat, egg_parent, joint_map); } } @@ -634,11 +661,29 @@ convert_geom_node(GeomNode *node, const WorkingNodePath &node_path, void EggSaver:: convert_primitive(const GeomVertexData *vertex_data, const GeomPrimitive *primitive, - const RenderState *net_state, + const RenderState *geom_state, const RenderState *net_state, const LMatrix4 &net_mat, EggGroupNode *egg_parent, CharacterJointMap *joint_map) { GeomVertexReader reader(vertex_data); + // Make a zygote that will be duplicated for each primitive. + PT(EggPrimitive) egg_prim; + if (primitive->is_of_type(GeomTriangles::get_class_type())) { + egg_prim = new EggPolygon(); + } else if (primitive->is_of_type(GeomPatches::get_class_type())) { + egg_prim = new EggPatch(); + } else if (primitive->is_of_type(GeomPoints::get_class_type())) { + egg_prim = new EggPoint(); + } else if (primitive->is_of_type(GeomLines::get_class_type())) { + egg_prim = new EggLine(); + } else { + // Huh, an unknown geometry type. + return; + } + + // Apply render attributes. + apply_state_properties(egg_prim, geom_state); + // Check for a color scale. LVecBase4 color_scale(1.0f, 1.0f, 1.0f, 1.0f); const ColorScaleAttrib *csa; @@ -670,20 +715,20 @@ convert_primitive(const GeomVertexData *vertex_data, const MaterialAttrib *ma; if (net_state->get_attrib(ma)) { egg_mat = get_egg_material(ma->get_material()); + if (egg_mat != (EggMaterial *)NULL) { + egg_prim->set_material(egg_mat); + } } // Check for a texture. - EggTexture *egg_tex = (EggTexture *)NULL; const TextureAttrib *ta; if (net_state->get_attrib(ta)) { - egg_tex = get_egg_texture(ta->get_texture()); - } + EggTexture *egg_tex = get_egg_texture(ta->get_texture()); - // Check the texture environment - if ((ta != (const TextureAttrib *)NULL) && (egg_tex != (const EggTexture *)NULL)) { - TextureStage* tex_stage = ta->get_on_stage(0); - if (tex_stage != (const TextureStage *)NULL) { - switch (tex_stage->get_mode()) { + if (egg_tex != (EggTexture *)NULL) { + TextureStage *tex_stage = ta->get_on_stage(0); + if (tex_stage != (TextureStage *)NULL) { + switch (tex_stage->get_mode()) { case TextureStage::M_modulate: if (has_color_off == true) { egg_tex->set_env_type(EggTexture::ET_replace); @@ -708,7 +753,10 @@ convert_primitive(const GeomVertexData *vertex_data, break; default: break; + } } + + egg_prim->set_texture(egg_tex); } } @@ -717,73 +765,22 @@ convert_primitive(const GeomVertexData *vertex_data, const CullFaceAttrib *cfa; if (net_state->get_attrib(cfa)) { if (cfa->get_effective_mode() == CullFaceAttrib::M_cull_none) { - bface = true; - } - } - - // Check the depth write flag - only needed for AM_blend_no_occlude - bool has_depthwrite = false; - DepthWriteAttrib::Mode depthwrite = DepthWriteAttrib::M_on; - const DepthWriteAttrib *dwa; - if (net_state->get_attrib(dwa)) { - depthwrite = dwa->get_mode(); - has_depthwrite = true; - } - - // Check the transparency flag. - bool has_transparency = false; - TransparencyAttrib::Mode transparency = TransparencyAttrib::M_none; - const TransparencyAttrib *tra; - if (net_state->get_attrib(tra)) { - transparency = tra->get_mode(); - has_transparency = true; - } - if (has_transparency && (egg_tex != (EggTexture *)NULL)) { - EggRenderMode::AlphaMode tex_trans = EggRenderMode::AM_unspecified; - switch (transparency) { - case TransparencyAttrib::M_none: - tex_trans = EggRenderMode::AM_off; - break; - case TransparencyAttrib::M_alpha: - if (has_depthwrite && (depthwrite == DepthWriteAttrib::M_off)) { - tex_trans = EggRenderMode::AM_blend_no_occlude; - has_depthwrite = false; - } else { - tex_trans = EggRenderMode::AM_blend; - } - break; - case TransparencyAttrib::M_premultiplied_alpha: - tex_trans = EggRenderMode::AM_premultiplied; - break; - case TransparencyAttrib::M_multisample: - tex_trans = EggRenderMode::AM_ms; - break; - case TransparencyAttrib::M_multisample_mask: - tex_trans = EggRenderMode::AM_ms_mask; - break; - case TransparencyAttrib::M_binary: - tex_trans = EggRenderMode::AM_binary; - break; - case TransparencyAttrib::M_dual: - tex_trans = EggRenderMode::AM_dual; - break; - default: // intentional fall-through - break; - } - if (tex_trans != EggRenderMode::AM_unspecified) { - egg_tex->set_alpha_mode(tex_trans); + egg_prim->set_bface_flag(true); } } // Check for line thickness and such. - bool has_render_mode = false; - bool perspective = false; - PN_stdfloat thickness = 1; const RenderModeAttrib *rma; if (net_state->get_attrib(rma)) { - has_render_mode = true; - thickness = rma->get_thickness(); - perspective = rma->get_perspective(); + if (egg_prim->is_of_type(EggPoint::get_class_type())) { + EggPoint *egg_point = (EggPoint *)egg_prim.p(); + egg_point->set_thick(rma->get_thickness()); + egg_point->set_perspective(rma->get_perspective()); + + } else if (egg_prim->is_of_type(EggLine::get_class_type())) { + EggLine *egg_line = (EggLine *)egg_prim.p(); + egg_line->set_thick(rma->get_thickness()); + } } LNormal normal; @@ -793,48 +790,9 @@ convert_primitive(const GeomVertexData *vertex_data, int num_primitives = primitive->get_num_primitives(); int num_vertices = primitive->get_num_vertices_per_primitive(); - EggPrimitive *(*make_func)(void); - - if (primitive->is_of_type(GeomTriangles::get_class_type())) { - make_func = make_egg_polygon; - } else if (primitive->is_of_type(GeomPatches::get_class_type())) { - make_func = make_egg_patch; - } else if (primitive->is_of_type(GeomPoints::get_class_type())) { - make_func = make_egg_point; - } else if (primitive->is_of_type(GeomLines::get_class_type())) { - make_func = make_egg_line; - } else { - // Huh, an unknown geometry type. - return; - } - for (int i = 0; i < num_primitives; ++i) { - PT(EggPrimitive) egg_prim = (*make_func)(); - - egg_parent->add_child(egg_prim); - - if (egg_mat != (EggMaterial *)NULL) { - egg_prim->set_material(egg_mat); - } - if (egg_tex != (EggTexture *)NULL) { - egg_prim->set_texture(egg_tex); - } - - if (bface) { - egg_prim->set_bface_flag(true); - } - - if (has_render_mode) { - if (egg_prim->is_of_type(EggPoint::get_class_type())) { - EggPoint *egg_point = (EggPoint *)egg_prim.p(); - egg_point->set_thick(thickness); - egg_point->set_perspective(perspective); - - } else if (egg_prim->is_of_type(EggLine::get_class_type())) { - EggLine *egg_line = (EggLine *)egg_prim.p(); - egg_line->set_thick(thickness); - } - } + PT(EggPrimitive) egg_child = egg_prim->make_copy(); + egg_parent->add_child(egg_child); for (int j = 0; j < num_vertices; j++) { EggVertex egg_vert; @@ -898,7 +856,7 @@ convert_primitive(const GeomVertexData *vertex_data, } } - egg_prim->add_vertex(new_egg_vert); + egg_child->add_vertex(new_egg_vert); } } } @@ -1004,6 +962,97 @@ apply_node_properties(EggGroup *egg_group, PandaNode *node, bool allow_backstage any_applied = true; } + const RenderState *state = node->get_state(); + if (apply_state_properties(egg_group, state)) { + return true; + } + + return any_applied; +} + +/** + * Applies any special render state settings on the primitive or group. + * Returns true if any were applied, false otherwise. + */ +bool EggSaver:: +apply_state_properties(EggRenderMode *egg_render_mode, const RenderState *state) { + if (state->is_empty()) { + return false; + } + + bool any_applied = false; + + // Check the transparency mode. + const TransparencyAttrib *tra; + if (state->get_attrib(tra)) { + EggRenderMode::AlphaMode tex_trans = EggRenderMode::AM_unspecified; + switch (tra->get_mode()) { + case TransparencyAttrib::M_none: + tex_trans = EggRenderMode::AM_off; + break; + case TransparencyAttrib::M_alpha: + tex_trans = EggRenderMode::AM_blend; + break; + case TransparencyAttrib::M_premultiplied_alpha: + tex_trans = EggRenderMode::AM_premultiplied; + break; + case TransparencyAttrib::M_multisample: + tex_trans = EggRenderMode::AM_ms; + break; + case TransparencyAttrib::M_multisample_mask: + tex_trans = EggRenderMode::AM_ms_mask; + break; + case TransparencyAttrib::M_binary: + tex_trans = EggRenderMode::AM_binary; + break; + case TransparencyAttrib::M_dual: + tex_trans = EggRenderMode::AM_dual; + break; + default: // intentional fall-through + break; + } + egg_render_mode->set_alpha_mode(tex_trans); + } + + const DepthWriteAttrib *dwa; + if (state->get_attrib(dwa)) { + if (dwa->get_mode() != DepthWriteAttrib::M_off) { + egg_render_mode->set_depth_write_mode(EggRenderMode::DWM_on); + + } else if (egg_render_mode->get_alpha_mode() == EggRenderMode::AM_blend) { + // AM_blend_no_occlude is like AM_blend but also implies DWM_off. + egg_render_mode->set_alpha_mode(EggRenderMode::AM_blend_no_occlude); + + } else { + egg_render_mode->set_depth_write_mode(EggRenderMode::DWM_off); + } + any_applied = true; + } + + const DepthTestAttrib *dta; + if (state->get_attrib(dta)) { + RenderAttrib::PandaCompareFunc mode = dta->get_mode(); + if (mode == DepthTestAttrib::M_none || mode == DepthTestAttrib::M_always) { + egg_render_mode->set_depth_test_mode(EggRenderMode::DTM_off); + } else { + egg_render_mode->set_depth_test_mode(EggRenderMode::DTM_on); + } + any_applied = true; + } + + const DepthOffsetAttrib *doa; + if (state->get_attrib(doa)) { + egg_render_mode->set_depth_offset(doa->get_offset()); + any_applied = true; + } + + const CullBinAttrib *cba; + if (state->get_attrib(cba)) { + egg_render_mode->set_bin(cba->get_bin_name()); + egg_render_mode->set_draw_order(cba->get_draw_order()); + any_applied = true; + } + return any_applied; } @@ -1250,35 +1299,3 @@ get_egg_texture(Texture *tex) { return NULL; } - -/** - * A factory function to make a new EggPolygon instance. - */ -EggPrimitive *EggSaver:: -make_egg_polygon() { - return new EggPolygon; -} - -/** - * A factory function to make a new EggPatch instance. - */ -EggPrimitive *EggSaver:: -make_egg_patch() { - return new EggPatch; -} - -/** - * A factory function to make a new EggPoint instance. - */ -EggPrimitive *EggSaver:: -make_egg_point() { - return new EggPoint; -} - -/** - * A factory function to make a new EggLine instance. - */ -EggPrimitive *EggSaver:: -make_egg_line() { - return new EggLine; -} diff --git a/panda/src/egg2pg/eggSaver.h b/panda/src/egg2pg/eggSaver.h index 170e5fe46c..a361591241 100644 --- a/panda/src/egg2pg/eggSaver.h +++ b/panda/src/egg2pg/eggSaver.h @@ -55,6 +55,7 @@ PUBLISHED: EggSaver(EggData *data = NULL); void add_node(PandaNode *node); + void add_subgraph(PandaNode *root); INLINE EggData *get_egg_data() const; private: @@ -84,6 +85,7 @@ private: EggGroupNode *egg_parent, bool has_decal, CharacterJointMap *jointMap=NULL); void convert_primitive(const GeomVertexData *vertex_data, const GeomPrimitive *primitive, + const RenderState *geom_state, const RenderState *net_state, const LMatrix4 &net_mat, EggGroupNode *egg_parent, CharacterJointMap *jointMap); @@ -91,17 +93,13 @@ private: void recurse_nodes(const WorkingNodePath &node_path, EggGroupNode *egg_parent, bool has_decal, CharacterJointMap *joint_map); bool apply_node_properties(EggGroup *egg_group, PandaNode *node, bool allow_backstage = true); + bool apply_state_properties(EggRenderMode *egg_render_mode, const RenderState *state); bool apply_tags(EggGroup *egg_group, PandaNode *node); bool apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag); EggMaterial *get_egg_material(Material *tex); EggTexture *get_egg_texture(Texture *tex); - static EggPrimitive *make_egg_polygon(); - static EggPrimitive *make_egg_patch(); - static EggPrimitive *make_egg_point(); - static EggPrimitive *make_egg_line(); - PT(EggData) _data; PT(EggVertexPool) _vpool; diff --git a/panda/src/egg2pg/save_egg_file.cxx b/panda/src/egg2pg/save_egg_file.cxx index db129802ba..95afdf5be2 100644 --- a/panda/src/egg2pg/save_egg_file.cxx +++ b/panda/src/egg2pg/save_egg_file.cxx @@ -31,7 +31,13 @@ save_egg_file(const Filename &filename, PandaNode *node, CoordinateSystem cs) { data->set_coordinate_system(cs); EggSaver saver(data); - saver.add_node(node); + if (node->is_of_type(ModelRoot::get_class_type())) { + // If this is a ModelRoot, only write the nodes below it. Otherwise we + // end up inserting a node when we do a bam2egg. + saver.add_subgraph(node); + } else { + saver.add_node(node); + } return data->write_egg(filename); } @@ -43,6 +49,12 @@ save_egg_file(const Filename &filename, PandaNode *node, CoordinateSystem cs) { bool save_egg_data(EggData *data, PandaNode *node) { EggSaver saver(data); - saver.add_node(node); + if (node->is_of_type(ModelRoot::get_class_type())) { + // If this is a ModelRoot, only write the nodes below it. Otherwise we + // end up inserting a node when we do a bam2egg. + saver.add_subgraph(node); + } else { + saver.add_node(node); + } return true; }