mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Fix various issues in bam2egg:
* No longer inserts an extra root group for the ModelRoot * Support depth test, offset and cull bin attributes * Preserve non-GeomNodes under Character * Render attributes are applied on group level if possible
This commit is contained in:
parent
08ea4bf2e5
commit
0bdafe45ce
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
TypeHandle EggLine::_type_handle;
|
TypeHandle EggLine::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -26,6 +25,14 @@ EggLine::
|
|||||||
clear();
|
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.
|
* Writes the point to the indicated output stream in Egg format.
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,8 @@ PUBLISHED:
|
|||||||
INLINE EggLine &operator = (const EggLine ©);
|
INLINE EggLine &operator = (const EggLine ©);
|
||||||
virtual ~EggLine();
|
virtual ~EggLine();
|
||||||
|
|
||||||
|
virtual EggLine *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
INLINE bool has_thick() const;
|
INLINE bool has_thick() const;
|
||||||
|
@ -17,6 +17,14 @@
|
|||||||
|
|
||||||
TypeHandle EggNurbsCurve::_type_handle;
|
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
|
* Prepares a new curve definition with the indicated order and number of
|
||||||
* knots. This also implies a particular number of vertices as well (the
|
* knots. This also implies a particular number of vertices as well (the
|
||||||
|
@ -29,6 +29,8 @@ PUBLISHED:
|
|||||||
INLINE EggNurbsCurve(const EggNurbsCurve ©);
|
INLINE EggNurbsCurve(const EggNurbsCurve ©);
|
||||||
INLINE EggNurbsCurve &operator = (const EggNurbsCurve ©);
|
INLINE EggNurbsCurve &operator = (const EggNurbsCurve ©);
|
||||||
|
|
||||||
|
virtual EggNurbsCurve *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
void setup(int order, int num_knots);
|
void setup(int order, int num_knots);
|
||||||
|
|
||||||
INLINE void set_order(int order);
|
INLINE void set_order(int order);
|
||||||
|
@ -17,6 +17,14 @@
|
|||||||
|
|
||||||
TypeHandle EggNurbsSurface::_type_handle;
|
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
|
* Prepares a new surface definition with the indicated order and number of
|
||||||
* knots in each dimension. This also implies a particular number of vertices
|
* knots in each dimension. This also implies a particular number of vertices
|
||||||
|
@ -36,6 +36,8 @@ PUBLISHED:
|
|||||||
INLINE EggNurbsSurface(const EggNurbsSurface ©);
|
INLINE EggNurbsSurface(const EggNurbsSurface ©);
|
||||||
INLINE EggNurbsSurface &operator = (const EggNurbsSurface ©);
|
INLINE EggNurbsSurface &operator = (const EggNurbsSurface ©);
|
||||||
|
|
||||||
|
virtual EggNurbsSurface *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
void setup(int u_order, int v_order,
|
void setup(int u_order, int v_order,
|
||||||
int num_u_knots, int num_v_knots);
|
int num_u_knots, int num_v_knots);
|
||||||
|
|
||||||
|
@ -21,6 +21,13 @@
|
|||||||
|
|
||||||
TypeHandle EggPatch::_type_handle;
|
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.
|
* Writes the patch to the indicated output stream in Egg format.
|
||||||
|
@ -28,6 +28,8 @@ PUBLISHED:
|
|||||||
INLINE EggPatch(const EggPatch ©);
|
INLINE EggPatch(const EggPatch ©);
|
||||||
INLINE EggPatch &operator = (const EggPatch ©);
|
INLINE EggPatch &operator = (const EggPatch ©);
|
||||||
|
|
||||||
|
virtual EggPatch *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -17,6 +17,13 @@
|
|||||||
|
|
||||||
TypeHandle EggPoint::_type_handle;
|
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
|
* Cleans up modeling errors in whatever context this makes sense. For
|
||||||
|
@ -28,6 +28,8 @@ PUBLISHED:
|
|||||||
INLINE EggPoint(const EggPoint ©);
|
INLINE EggPoint(const EggPoint ©);
|
||||||
INLINE EggPoint &operator = (const EggPoint ©);
|
INLINE EggPoint &operator = (const EggPoint ©);
|
||||||
|
|
||||||
|
virtual EggPoint *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
INLINE bool has_thick() const;
|
INLINE bool has_thick() const;
|
||||||
INLINE double get_thick() const;
|
INLINE double get_thick() const;
|
||||||
INLINE void set_thick(double thick);
|
INLINE void set_thick(double thick);
|
||||||
|
@ -21,6 +21,13 @@
|
|||||||
|
|
||||||
TypeHandle EggPolygon::_type_handle;
|
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
|
* Cleans up modeling errors in whatever context this makes sense. For
|
||||||
|
@ -27,6 +27,8 @@ PUBLISHED:
|
|||||||
INLINE EggPolygon(const EggPolygon ©);
|
INLINE EggPolygon(const EggPolygon ©);
|
||||||
INLINE EggPolygon &operator = (const EggPolygon ©);
|
INLINE EggPolygon &operator = (const EggPolygon ©);
|
||||||
|
|
||||||
|
virtual EggPolygon *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
virtual bool cleanup();
|
virtual bool cleanup();
|
||||||
|
|
||||||
bool calculate_normal(LNormald &result, CoordinateSystem cs = CS_default) const;
|
bool calculate_normal(LNormald &result, CoordinateSystem cs = CS_default) const;
|
||||||
|
@ -72,6 +72,8 @@ PUBLISHED:
|
|||||||
INLINE EggPrimitive &operator = (const EggPrimitive ©);
|
INLINE EggPrimitive &operator = (const EggPrimitive ©);
|
||||||
INLINE ~EggPrimitive();
|
INLINE ~EggPrimitive();
|
||||||
|
|
||||||
|
virtual EggPrimitive *make_copy() const=0;
|
||||||
|
|
||||||
virtual EggRenderMode *determine_alpha_mode();
|
virtual EggRenderMode *determine_alpha_mode();
|
||||||
virtual EggRenderMode *determine_depth_write_mode();
|
virtual EggRenderMode *determine_depth_write_mode();
|
||||||
virtual EggRenderMode *determine_depth_test_mode();
|
virtual EggRenderMode *determine_depth_test_mode();
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
TypeHandle EggTriangleFan::_type_handle;
|
TypeHandle EggTriangleFan::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -27,6 +26,14 @@ EggTriangleFan::
|
|||||||
clear();
|
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.
|
* Writes the triangle fan to the indicated output stream in Egg format.
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,8 @@ PUBLISHED:
|
|||||||
INLINE EggTriangleFan &operator = (const EggTriangleFan ©);
|
INLINE EggTriangleFan &operator = (const EggTriangleFan ©);
|
||||||
virtual ~EggTriangleFan();
|
virtual ~EggTriangleFan();
|
||||||
|
|
||||||
|
virtual EggTriangleFan *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
virtual void apply_first_attribute();
|
virtual void apply_first_attribute();
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
TypeHandle EggTriangleStrip::_type_handle;
|
TypeHandle EggTriangleStrip::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -27,6 +26,14 @@ EggTriangleStrip::
|
|||||||
clear();
|
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.
|
* Writes the triangle strip to the indicated output stream in Egg format.
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,8 @@ PUBLISHED:
|
|||||||
INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©);
|
INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©);
|
||||||
virtual ~EggTriangleStrip();
|
virtual ~EggTriangleStrip();
|
||||||
|
|
||||||
|
virtual EggTriangleStrip *make_copy() const OVERRIDE;
|
||||||
|
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -23,8 +23,11 @@
|
|||||||
#include "colorAttrib.h"
|
#include "colorAttrib.h"
|
||||||
#include "materialAttrib.h"
|
#include "materialAttrib.h"
|
||||||
#include "textureAttrib.h"
|
#include "textureAttrib.h"
|
||||||
|
#include "cullBinAttrib.h"
|
||||||
#include "cullFaceAttrib.h"
|
#include "cullFaceAttrib.h"
|
||||||
#include "transparencyAttrib.h"
|
#include "transparencyAttrib.h"
|
||||||
|
#include "depthTestAttrib.h"
|
||||||
|
#include "depthOffsetAttrib.h"
|
||||||
#include "depthWriteAttrib.h"
|
#include "depthWriteAttrib.h"
|
||||||
#include "lodNode.h"
|
#include "lodNode.h"
|
||||||
#include "switchNode.h"
|
#include "switchNode.h"
|
||||||
@ -101,6 +104,26 @@ add_node(PandaNode *node) {
|
|||||||
_vpool = NULL;
|
_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
|
* Converts the indicated node to the corresponding Egg constructs, by first
|
||||||
* determining what kind of node it is.
|
* 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) {
|
EggGroupNode *egg_parent, bool has_decal) {
|
||||||
|
|
||||||
// A sequence node gets converted to an ordinary EggGroup, we only apply the
|
// 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());
|
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);
|
egg_parent->add_child(egg_group);
|
||||||
apply_node_properties(egg_group, node);
|
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.
|
// Now get out all the various kinds of geometry.
|
||||||
int num_geoms = node->get_num_geoms();
|
int num_geoms = node->get_num_geoms();
|
||||||
for (int i = 0; i < num_geoms; ++i) {
|
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);
|
const Geom *geom = node->get_geom(i);
|
||||||
int num_primitives = geom->get_num_primitives();
|
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(GeomPrimitive) simple = primitive->decompose();
|
||||||
CPT(GeomVertexData) vdata = geom->get_vertex_data();
|
CPT(GeomVertexData) vdata = geom->get_vertex_data();
|
||||||
// vdata = vdata->animate_vertices(true, Thread::get_current_thread());
|
// 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);
|
net_mat, egg_parent, joint_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,11 +661,29 @@ convert_geom_node(GeomNode *node, const WorkingNodePath &node_path,
|
|||||||
void EggSaver::
|
void EggSaver::
|
||||||
convert_primitive(const GeomVertexData *vertex_data,
|
convert_primitive(const GeomVertexData *vertex_data,
|
||||||
const GeomPrimitive *primitive,
|
const GeomPrimitive *primitive,
|
||||||
const RenderState *net_state,
|
const RenderState *geom_state, const RenderState *net_state,
|
||||||
const LMatrix4 &net_mat, EggGroupNode *egg_parent,
|
const LMatrix4 &net_mat, EggGroupNode *egg_parent,
|
||||||
CharacterJointMap *joint_map) {
|
CharacterJointMap *joint_map) {
|
||||||
GeomVertexReader reader(vertex_data);
|
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.
|
// Check for a color scale.
|
||||||
LVecBase4 color_scale(1.0f, 1.0f, 1.0f, 1.0f);
|
LVecBase4 color_scale(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
const ColorScaleAttrib *csa;
|
const ColorScaleAttrib *csa;
|
||||||
@ -670,20 +715,20 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||||||
const MaterialAttrib *ma;
|
const MaterialAttrib *ma;
|
||||||
if (net_state->get_attrib(ma)) {
|
if (net_state->get_attrib(ma)) {
|
||||||
egg_mat = get_egg_material(ma->get_material());
|
egg_mat = get_egg_material(ma->get_material());
|
||||||
|
if (egg_mat != (EggMaterial *)NULL) {
|
||||||
|
egg_prim->set_material(egg_mat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a texture.
|
// Check for a texture.
|
||||||
EggTexture *egg_tex = (EggTexture *)NULL;
|
|
||||||
const TextureAttrib *ta;
|
const TextureAttrib *ta;
|
||||||
if (net_state->get_attrib(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 (egg_tex != (EggTexture *)NULL) {
|
||||||
if ((ta != (const TextureAttrib *)NULL) && (egg_tex != (const EggTexture *)NULL)) {
|
TextureStage *tex_stage = ta->get_on_stage(0);
|
||||||
TextureStage* tex_stage = ta->get_on_stage(0);
|
if (tex_stage != (TextureStage *)NULL) {
|
||||||
if (tex_stage != (const TextureStage *)NULL) {
|
switch (tex_stage->get_mode()) {
|
||||||
switch (tex_stage->get_mode()) {
|
|
||||||
case TextureStage::M_modulate:
|
case TextureStage::M_modulate:
|
||||||
if (has_color_off == true) {
|
if (has_color_off == true) {
|
||||||
egg_tex->set_env_type(EggTexture::ET_replace);
|
egg_tex->set_env_type(EggTexture::ET_replace);
|
||||||
@ -708,7 +753,10 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
egg_prim->set_texture(egg_tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,73 +765,22 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||||||
const CullFaceAttrib *cfa;
|
const CullFaceAttrib *cfa;
|
||||||
if (net_state->get_attrib(cfa)) {
|
if (net_state->get_attrib(cfa)) {
|
||||||
if (cfa->get_effective_mode() == CullFaceAttrib::M_cull_none) {
|
if (cfa->get_effective_mode() == CullFaceAttrib::M_cull_none) {
|
||||||
bface = true;
|
egg_prim->set_bface_flag(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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for line thickness and such.
|
// Check for line thickness and such.
|
||||||
bool has_render_mode = false;
|
|
||||||
bool perspective = false;
|
|
||||||
PN_stdfloat thickness = 1;
|
|
||||||
const RenderModeAttrib *rma;
|
const RenderModeAttrib *rma;
|
||||||
if (net_state->get_attrib(rma)) {
|
if (net_state->get_attrib(rma)) {
|
||||||
has_render_mode = true;
|
if (egg_prim->is_of_type(EggPoint::get_class_type())) {
|
||||||
thickness = rma->get_thickness();
|
EggPoint *egg_point = (EggPoint *)egg_prim.p();
|
||||||
perspective = rma->get_perspective();
|
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;
|
LNormal normal;
|
||||||
@ -793,48 +790,9 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||||||
int num_primitives = primitive->get_num_primitives();
|
int num_primitives = primitive->get_num_primitives();
|
||||||
int num_vertices = primitive->get_num_vertices_per_primitive();
|
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) {
|
for (int i = 0; i < num_primitives; ++i) {
|
||||||
PT(EggPrimitive) egg_prim = (*make_func)();
|
PT(EggPrimitive) egg_child = egg_prim->make_copy();
|
||||||
|
egg_parent->add_child(egg_child);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < num_vertices; j++) {
|
for (int j = 0; j < num_vertices; j++) {
|
||||||
EggVertex egg_vert;
|
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;
|
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;
|
return any_applied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,35 +1299,3 @@ get_egg_texture(Texture *tex) {
|
|||||||
|
|
||||||
return NULL;
|
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;
|
|
||||||
}
|
|
||||||
|
@ -55,6 +55,7 @@ PUBLISHED:
|
|||||||
EggSaver(EggData *data = NULL);
|
EggSaver(EggData *data = NULL);
|
||||||
|
|
||||||
void add_node(PandaNode *node);
|
void add_node(PandaNode *node);
|
||||||
|
void add_subgraph(PandaNode *root);
|
||||||
INLINE EggData *get_egg_data() const;
|
INLINE EggData *get_egg_data() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -84,6 +85,7 @@ private:
|
|||||||
EggGroupNode *egg_parent, bool has_decal, CharacterJointMap *jointMap=NULL);
|
EggGroupNode *egg_parent, bool has_decal, CharacterJointMap *jointMap=NULL);
|
||||||
void convert_primitive(const GeomVertexData *vertex_data,
|
void convert_primitive(const GeomVertexData *vertex_data,
|
||||||
const GeomPrimitive *primitive,
|
const GeomPrimitive *primitive,
|
||||||
|
const RenderState *geom_state,
|
||||||
const RenderState *net_state,
|
const RenderState *net_state,
|
||||||
const LMatrix4 &net_mat, EggGroupNode *egg_parent,
|
const LMatrix4 &net_mat, EggGroupNode *egg_parent,
|
||||||
CharacterJointMap *jointMap);
|
CharacterJointMap *jointMap);
|
||||||
@ -91,17 +93,13 @@ private:
|
|||||||
void recurse_nodes(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
|
void recurse_nodes(const WorkingNodePath &node_path, EggGroupNode *egg_parent,
|
||||||
bool has_decal, CharacterJointMap *joint_map);
|
bool has_decal, CharacterJointMap *joint_map);
|
||||||
bool apply_node_properties(EggGroup *egg_group, PandaNode *node, bool allow_backstage = true);
|
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_tags(EggGroup *egg_group, PandaNode *node);
|
||||||
bool apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag);
|
bool apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag);
|
||||||
|
|
||||||
EggMaterial *get_egg_material(Material *tex);
|
EggMaterial *get_egg_material(Material *tex);
|
||||||
EggTexture *get_egg_texture(Texture *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(EggData) _data;
|
||||||
|
|
||||||
PT(EggVertexPool) _vpool;
|
PT(EggVertexPool) _vpool;
|
||||||
|
@ -31,7 +31,13 @@ save_egg_file(const Filename &filename, PandaNode *node, CoordinateSystem cs) {
|
|||||||
data->set_coordinate_system(cs);
|
data->set_coordinate_system(cs);
|
||||||
|
|
||||||
EggSaver saver(data);
|
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);
|
return data->write_egg(filename);
|
||||||
}
|
}
|
||||||
@ -43,6 +49,12 @@ save_egg_file(const Filename &filename, PandaNode *node, CoordinateSystem cs) {
|
|||||||
bool
|
bool
|
||||||
save_egg_data(EggData *data, PandaNode *node) {
|
save_egg_data(EggData *data, PandaNode *node) {
|
||||||
EggSaver saver(data);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user