fix some bam issues

This commit is contained in:
David Rose 2005-04-11 23:10:21 +00:00
parent 86f7689b43
commit c7d4e746fa
12 changed files with 374 additions and 105 deletions

View File

@ -62,6 +62,42 @@ get_part(int n) const {
return _parts[n];
}
////////////////////////////////////////////////////////////////////
// Function: Character::find_joint
// Access: Published
// Description: Returns a pointer to the joint with the given name,
// if there is such a joint, or NULL if there is no such
// joint. This will not return a pointer to a slider.
////////////////////////////////////////////////////////////////////
INLINE CharacterJoint *Character::
find_joint(const string &name) const {
PartGroup *part = get_bundle()->find_child(name);
if (part != (PartGroup *)NULL &&
part->is_of_type(CharacterJoint::get_class_type())) {
return DCAST(CharacterJoint, part);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Character::find_slider
// Access: Published
// Description: Returns a pointer to the slider with the given name,
// if there is such a slider, or NULL if there is no such
// slider. This will not return a pointer to a joint.
////////////////////////////////////////////////////////////////////
INLINE CharacterSlider *Character::
find_slider(const string &name) const {
PartGroup *part = get_bundle()->find_child(name);
if (part != (PartGroup *)NULL &&
part->is_of_type(CharacterSlider::get_class_type())) {
return DCAST(CharacterSlider, part);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Character::write_parts
// Access: Published

View File

@ -377,49 +377,69 @@ r_copy_char(PandaNode *dest, const PandaNode *source,
////////////////////////////////////////////////////////////////////
PT(Geom) Character::
copy_geom(const Geom *source, const Character *from) {
GeomBindType bind;
PTA_ushort index;
PTA_Vertexf coords;
PTA_Normalf norms;
PTA_Colorf colors;
PTA_TexCoordf texcoords;
PT(Geom) dest = (Geom *)source;
source->get_coords(coords, index);
if ((coords != (void *)NULL) && (coords == (from->_cv._coords))) {
if (dest == source) {
dest = source->make_copy();
if (source->is_of_type(qpGeom::get_class_type())) {
CPT(qpGeom) qpsource = DCAST(qpGeom, source);
CPT(qpGeomVertexFormat) format = qpsource->get_vertex_data()->get_format();
if (format->get_animation().get_animation_type() ==
qpGeomVertexAnimationSpec::AT_none) {
// Not animated, so never mind.
return (Geom *)source;
}
dest->set_coords(_cv._coords, index);
}
source->get_normals(norms, bind, index);
if (bind != G_OFF && norms == from->_cv._norms) {
if (dest == source) {
dest = source->make_copy();
PT(qpGeom) dest = new qpGeom(*qpsource);
PT(qpGeomVertexData) vdata = dest->modify_vertex_data();
vdata->set_transform_palette(redirect_transform_palette(vdata->get_transform_palette()));
vdata->set_transform_blend_palette(redirect_transform_blend_palette(vdata->get_transform_blend_palette()));
vdata->set_slider_table(redirect_slider_table(vdata->get_slider_table()));
return dest.p();
} else {
GeomBindType bind;
PTA_ushort index;
PTA_Vertexf coords;
PTA_Normalf norms;
PTA_Colorf colors;
PTA_TexCoordf texcoords;
PT(Geom) dest = (Geom *)source;
source->get_coords(coords, index);
if ((coords != (void *)NULL) && (coords == (from->_cv._coords))) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_coords(_cv._coords, index);
}
dest->set_normals(_cv._norms, bind, index);
}
source->get_colors(colors, bind, index);
if (bind != G_OFF && colors == from->_cv._colors) {
if (dest == source) {
dest = source->make_copy();
source->get_normals(norms, bind, index);
if (bind != G_OFF && norms == from->_cv._norms) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_normals(_cv._norms, bind, index);
}
dest->set_colors(_cv._colors, bind, index);
}
source->get_texcoords(texcoords, bind, index);
if (bind != G_OFF && texcoords == from->_cv._texcoords) {
if (dest == source) {
dest = source->make_copy();
source->get_colors(colors, bind, index);
if (bind != G_OFF && colors == from->_cv._colors) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_colors(_cv._colors, bind, index);
}
dest->set_texcoords(_cv._texcoords, bind, index);
source->get_texcoords(texcoords, bind, index);
if (bind != G_OFF && texcoords == from->_cv._texcoords) {
if (dest == source) {
dest = source->make_copy();
}
dest->set_texcoords(_cv._texcoords, bind, index);
}
return dest;
}
return dest;
}
////////////////////////////////////////////////////////////////////
@ -478,6 +498,103 @@ copy_node_pointers(const Character *from, const Character::NodeMap &node_map) {
}
}
////////////////////////////////////////////////////////////////////
// Function: Character::redirect_transform_palette
// Access: Public
// Description: Creates a new TransformPalette, similar to the
// indicated one, with the joint and slider pointers
// redirected into this object.
////////////////////////////////////////////////////////////////////
CPT(TransformPalette) Character::
redirect_transform_palette(const TransformPalette *source) {
if (source == (TransformPalette *)NULL) {
return NULL;
}
PT(TransformPalette) dest = new TransformPalette(*source);
int num_transforms = dest->get_num_transforms();
for (int i = 0; i < num_transforms; ++i) {
const VertexTransform *vt = dest->get_transform(i);
if (vt->is_of_type(JointVertexTransform::get_class_type())) {
const JointVertexTransform *jvt = DCAST(JointVertexTransform, vt);
CharacterJoint *joint = find_joint(jvt->get_joint()->get_name());
if (joint != (CharacterJoint *)NULL) {
CPT(JointVertexTransform) new_jvt = new JointVertexTransform(joint);
dest->set_transform(i, new_jvt);
}
}
}
return TransformPalette::register_palette(dest);
}
////////////////////////////////////////////////////////////////////
// Function: Character::redirect_transform_blend_palette
// Access: Public
// Description: Creates a new TransformBlendPalette, similar to the
// indicated one, with the joint and slider pointers
// redirected into this object.
////////////////////////////////////////////////////////////////////
CPT(TransformBlendPalette) Character::
redirect_transform_blend_palette(const TransformBlendPalette *source) {
if (source == (TransformBlendPalette *)NULL) {
return NULL;
}
PT(TransformBlendPalette) dest = new TransformBlendPalette(*source);
int num_blends = dest->get_num_blends();
for (int i = 0; i < num_blends; ++i) {
TransformBlend blend = dest->get_blend(i);
int num_transforms = blend.get_num_transforms();
for (int j = 0; j < num_transforms; ++j) {
const VertexTransform *vt = blend.get_transform(j);
if (vt->is_of_type(JointVertexTransform::get_class_type())) {
const JointVertexTransform *jvt = DCAST(JointVertexTransform, vt);
CharacterJoint *joint = find_joint(jvt->get_joint()->get_name());
if (joint != (CharacterJoint *)NULL) {
CPT(JointVertexTransform) new_jvt = new JointVertexTransform(joint);
blend.set_transform(j, new_jvt);
}
}
}
dest->set_blend(i, blend);
}
return dest;
}
////////////////////////////////////////////////////////////////////
// Function: Character::redirect_slider_table
// Access: Public
// Description: Creates a new SliderTable, similar to the
// indicated one, with the joint and slider pointers
// redirected into this object.
////////////////////////////////////////////////////////////////////
CPT(SliderTable) Character::
redirect_slider_table(const SliderTable *source) {
if (source == (SliderTable *)NULL) {
return NULL;
}
PT(SliderTable) dest = new SliderTable(*source);
int num_sliders = dest->get_num_sliders();
for (int i = 0; i < num_sliders; ++i) {
const VertexSlider *vs = dest->get_slider(i);
if (vs->is_of_type(CharacterVertexSlider::get_class_type())) {
const CharacterVertexSlider *cvs = DCAST(CharacterVertexSlider, vs);
CharacterSlider *slider = find_slider(cvs->get_char_slider()->get_name());
if (slider != (CharacterSlider *)NULL) {
CPT(CharacterVertexSlider) new_cvs = new CharacterVertexSlider(slider);
dest->set_slider(i, new_cvs);
}
}
}
return SliderTable::register_table(dest);
}
////////////////////////////////////////////////////////////////////
// Function: Character::register_with_read_factory

View File

@ -22,12 +22,16 @@
#include "pandabase.h"
#include "computedVertices.h"
#include "characterJoint.h"
#include "characterSlider.h"
#include "partBundleNode.h"
#include "vector_PartGroupStar.h"
#include "pointerTo.h"
#include "geom.h"
#include "pStatCollector.h"
#include "transformPalette.h"
#include "transformBlendPalette.h"
#include "sliderTable.h"
class CharacterJointBundle;
class ComputedVertices;
@ -59,6 +63,9 @@ PUBLISHED:
INLINE int get_num_parts() const;
INLINE PartGroup *get_part(int n) const;
INLINE CharacterJoint *find_joint(const string &name) const;
INLINE CharacterSlider *find_slider(const string &name) const;
INLINE void write_parts(ostream &out) const;
INLINE void write_part_values(ostream &out) const;
@ -77,6 +84,9 @@ private:
const Character *from, NodeMap &node_map);
PT(Geom) copy_geom(const Geom *source, const Character *from);
void copy_node_pointers(const Character *from, const NodeMap &node_map);
CPT(TransformPalette) redirect_transform_palette(const TransformPalette *source);
CPT(TransformBlendPalette) redirect_transform_blend_palette(const TransformBlendPalette *source);
CPT(SliderTable) redirect_slider_table(const SliderTable *source);
// These are the actual dynamic vertex pools for this Character's
// ComputedVertices--the vertices that it will recompute each frame

View File

@ -168,12 +168,14 @@ part_to_node(PartGroup *part, const string &name) const {
// GeomNode. Look for a child of this node. If it doesn't have a
// child yet, add a GeomNode and return it. Otherwise, if it
// already has a child, return that.
if (node->is_geom_node() && node->get_name() == name) {
if (node->is_geom_node() &&
(name.empty() || node->get_name() == name)) {
return node;
}
for (int i = 0; i < node->get_num_children(); i++) {
PandaNode *child = node->get_child(i);
if (child->is_geom_node() && child->get_name() == name) {
if (child->is_geom_node() &&
(name.empty() || child->get_name() == name)) {
return child;
}
}
@ -683,8 +685,9 @@ determine_bin_home(EggBin *egg_bin) {
CharacterJoint *joint;
DCAST_INTO_R(joint, egg_to_part(egg_group), home);
egg_group->set_dcs_type(EggGroup::DC_default);
PT(GeomNode) geom_node = new GeomNode(egg_group->get_name());
joint->_geom_node = geom_node.p();
PT(PandaNode) geom_node = new PandaNode(egg_group->get_name());
joint->_geom_node = geom_node;
}
return home;

View File

@ -430,7 +430,9 @@ CData() {
INLINE qpGeomVertexData::CData::
CData(const qpGeomVertexData::CData &copy) :
_arrays(copy._arrays),
_transform_palette(copy._transform_palette),
_transform_blend_palette(copy._transform_blend_palette),
_slider_table(copy._slider_table),
_animated_vertices(copy._animated_vertices),
_animated_vertices_modified(copy._animated_vertices_modified),
_modified(copy._modified)

View File

@ -1174,7 +1174,7 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata, bool from_app) {
int num_morphs = _format->get_num_morphs();
for (int mi = 0; mi < num_morphs; mi++) {
CPT(InternalName) slider_name = _format->get_morph_slider(mi);
const VertexSlider *slider = table->get_slider(slider_name);
const VertexSlider *slider = table->find_slider(slider_name);
if (slider != (VertexSlider *)NULL) {
float slider_value = slider->get_slider();
if (slider_value != 0.0f) {

View File

@ -61,18 +61,39 @@ register_table(const SliderTable *table) {
return table;
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::get_num_sliders
// Access: Published
// Description: Returns the number of sliders in the palette.
////////////////////////////////////////////////////////////////////
INLINE int SliderTable::
get_num_sliders() const {
return _sliders.size();
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::get_slider
// Access: Published
// Description: Returns the nth slider in the palette.
////////////////////////////////////////////////////////////////////
INLINE const VertexSlider *SliderTable::
get_slider(int n) const {
nassertr(n >= 0 && n < (int)_sliders.size(), NULL);
return _sliders[n];
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::find_slider
// Access: Published
// Description: Returns the slider with the indicated name, or NULL
// if no slider in the table has that name.
////////////////////////////////////////////////////////////////////
INLINE const VertexSlider *SliderTable::
get_slider(const InternalName *name) const {
Sliders::const_iterator si;
si = _sliders.find(name);
if (si != _sliders.end()) {
return (*si).second;
find_slider(const InternalName *name) const {
SlidersByName::const_iterator sni;
sni = _sliders_by_name.find(name);
if (sni != _sliders_by_name.end()) {
return (*sni).second;
}
return NULL;
}
@ -85,7 +106,7 @@ get_slider(const InternalName *name) const {
////////////////////////////////////////////////////////////////////
INLINE bool SliderTable::
has_slider(const InternalName *name) const {
return (get_slider(name) != (VertexSlider *)NULL);
return (find_slider(name) != (VertexSlider *)NULL);
}
////////////////////////////////////////////////////////////////////

View File

@ -41,7 +41,8 @@ SliderTable() :
SliderTable::
SliderTable(const SliderTable &copy) :
_is_registered(false),
_sliders(copy._sliders)
_sliders(copy._sliders),
_sliders_by_name(copy._sliders_by_name)
{
}
@ -54,6 +55,7 @@ void SliderTable::
operator = (const SliderTable &copy) {
nassertv(!_is_registered);
_sliders = copy._sliders;
_sliders_by_name = copy._sliders_by_name;
}
////////////////////////////////////////////////////////////////////
@ -69,33 +71,73 @@ SliderTable::
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::remove_slider
// Function: SliderTable::set_slider
// Access: Published
// Description: Removes the named slider. Only valid for
// Description: Replaces the nth slider. Only valid for
// unregistered tables.
////////////////////////////////////////////////////////////////////
void SliderTable::
remove_slider(const InternalName *name) {
set_slider(int n, const VertexSlider *slider) {
nassertv(!_is_registered);
nassertv(n >= 0 && n < (int)_sliders.size());
Sliders::iterator si = _sliders.find(name);
if (si != _sliders.end()) {
_sliders.erase(si);
if (_sliders[n]->get_name() != slider->get_name()) {
// Not allowed to move a slider this way.
nassertv(!has_slider(slider->get_name()));
}
_sliders[n] = slider;
_sliders_by_name[slider->get_name()] = slider;
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::remove_slider
// Access: Published
// Description: Removes the nth slider. Only valid for
// unregistered tables.
////////////////////////////////////////////////////////////////////
void SliderTable::
remove_slider(int n) {
nassertv(!_is_registered);
nassertv(n >= 0 && n < (int)_sliders.size());
SlidersByName::iterator si = _sliders_by_name.find(_sliders[n]->get_name());
nassertv(si != _sliders_by_name.end());
_sliders_by_name.erase(si);
_sliders.erase(_sliders.begin() + n);
}
////////////////////////////////////////////////////////////////////
// Function: SliderTable::add_slider
// Access: Published
// Description: Adds a new slider to the table, or replaces an
// existing slider with the same name. Only valid for
// existing slider with the same name, and returns the
// index number of the new slider. Only valid for
// unregistered tables.
////////////////////////////////////////////////////////////////////
void SliderTable::
add_slider(VertexSlider *slider) {
nassertv(!_is_registered);
int SliderTable::
add_slider(const VertexSlider *slider) {
nassertr(!_is_registered, -1);
_sliders[slider->get_name()] = slider;
SlidersByName::iterator sni = _sliders_by_name.find(slider->get_name());
if (sni != _sliders_by_name.end()) {
// We've already got a slider with this name; replace it.
CPT(VertexSlider) orig_slider = (*sni).second;
Sliders::iterator si = find(_sliders.begin(), _sliders.end(), orig_slider);
nassertr(si != _sliders.end(), -1);
(*si) = slider;
(*sni).second = slider;
return si - _sliders.begin();
}
// This is the first slider with this name.
int new_index = (int)_sliders.size();
_sliders.push_back(slider);
_sliders_by_name[slider->get_name()] = slider;
return new_index;
}
////////////////////////////////////////////////////////////////////
@ -105,9 +147,8 @@ add_slider(VertexSlider *slider) {
////////////////////////////////////////////////////////////////////
void SliderTable::
write(ostream &out) const {
Sliders::const_iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
out << *(*si).second << "\n";
for (size_t i = 0; i < _sliders.size(); ++i) {
out << i << ". " << *_sliders[i] << "\n";
}
}
@ -122,7 +163,8 @@ do_register() {
Sliders::iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
bool inserted = (*si).second->_tables.insert(this).second;
const VertexSlider *slider = (*si);
bool inserted = ((VertexSlider *)slider)->_tables.insert(this).second;
nassertv(inserted);
}
_is_registered = true;
@ -140,7 +182,8 @@ do_unregister() {
Sliders::iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
(*si).second->_tables.erase(this);
const VertexSlider *slider = (*si);
((VertexSlider *)slider)->_tables.erase(this);
}
_is_registered = false;
}
@ -169,8 +212,8 @@ write_datagram(BamWriter *manager, Datagram &dg) {
dg.add_uint16(_sliders.size());
Sliders::const_iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
manager->write_pointer(dg, (*si).first);
manager->write_pointer(dg, (*si).second);
manager->write_pointer(dg, (*si)->get_name());
manager->write_pointer(dg, (*si));
}
manager->write_cdata(dg, _cycler);
@ -187,11 +230,14 @@ int SliderTable::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
for (size_t i = 0; i < _num_sliders; ++i) {
Sliders::iterator si;
for (si = _sliders.begin(); si != _sliders.end(); ++si) {
CPT(InternalName) name = DCAST(InternalName, p_list[pi++]);
PT(VertexSlider) slider = DCAST(VertexSlider, p_list[pi++]);
bool inserted = _sliders.insert(Sliders::value_type(name, slider)).second;
(*si) = slider;
bool inserted = _sliders_by_name.insert(SlidersByName::value_type(name, slider)).second;
nassertr(inserted, pi);
}
@ -229,10 +275,12 @@ void SliderTable::
fillin(DatagramIterator &scan, BamReader *manager) {
TypedWritable::fillin(scan, manager);
_num_sliders = scan.get_uint16();
for (size_t i = 0; i < _num_sliders; ++i) {
size_t num_sliders = scan.get_uint16();
_sliders.reserve(num_sliders);
for (size_t i = 0; i < num_sliders; ++i) {
manager->read_pointer(scan);
manager->read_pointer(scan);
_sliders.push_back(NULL);
}
manager->read_cdata(scan, _cycler);

View File

@ -55,13 +55,17 @@ PUBLISHED:
INLINE bool is_registered() const;
INLINE static CPT(SliderTable) register_table(const SliderTable *table);
INLINE const VertexSlider *get_slider(const InternalName *name) const;
INLINE int get_num_sliders() const;
INLINE const VertexSlider *get_slider(int n) const;
INLINE const VertexSlider *find_slider(const InternalName *name) const;
INLINE bool has_slider(const InternalName *name) const;
INLINE bool is_empty() const;
INLINE UpdateSeq get_modified() const;
void remove_slider(const InternalName *name);
void add_slider(VertexSlider *slider);
void set_slider(int n, const VertexSlider *slider);
void remove_slider(int n);
int add_slider(const VertexSlider *slider);
void write(ostream &out) const;
@ -73,11 +77,11 @@ private:
private:
bool _is_registered;
typedef pmap< CPT(InternalName), PT(VertexSlider) > Sliders;
typedef pvector< CPT(VertexSlider) > Sliders;
Sliders _sliders;
// This is only filled in while reading from the bam stream.
size_t _num_sliders;
typedef pmap< CPT(InternalName), const VertexSlider *> SlidersByName;
SlidersByName _sliders_by_name;
// This is the data that must be cycled between pipeline stages.
class EXPCL_PANDA CData : public CycleData {

View File

@ -177,6 +177,30 @@ get_weight(int n) const {
return _entries[n]._weight;
}
////////////////////////////////////////////////////////////////////
// Function: TransformBlend::set_transform
// Access: Published
// Description: Replaces the nth transform stored in the blend
// object.
////////////////////////////////////////////////////////////////////
INLINE void TransformBlend::
set_transform(int n, const VertexTransform *transform) {
nassertv(n >= 0 && n < (int)_entries.size());
_entries[n]._transform = transform;
}
////////////////////////////////////////////////////////////////////
// Function: TransformBlend::set_weight
// Access: Published
// Description: Replaces the weight associated with the nth transform
// stored in the blend object.
////////////////////////////////////////////////////////////////////
INLINE void TransformBlend::
set_weight(int n, float weight) {
nassertv(n >= 0 && n < (int)_entries.size());
_entries[n]._weight = weight;
}
////////////////////////////////////////////////////////////////////
// Function: TransformBlend::update_blend
// Access: Published

View File

@ -69,6 +69,8 @@ PUBLISHED:
INLINE int get_num_transforms() const;
INLINE const VertexTransform *get_transform(int n) const;
INLINE float get_weight(int n) const;
INLINE void set_transform(int n, const VertexTransform *transform);
INLINE void set_weight(int n, float weight);
INLINE void update_blend() const;

View File

@ -152,33 +152,35 @@ set_from_node(const NodePath &node_path, bool size_from_texels) {
qpGeomVertexReader texcoord(qpgeom->get_vertex_data());
qpGeomVertexReader vertex(qpgeom->get_vertex_data());
bool found_any = false;
for (int pi = 0; pi < qpgeom->get_num_primitives(); ++pi) {
const qpGeomPrimitive *primitive = qpgeom->get_primitive(pi);
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
int vert = primitive->get_vertex(vi);
texcoord.set_vertex(vert);
vertex.set_vertex(vert);
if (!found_any) {
min_uv = max_uv = texcoord.get_data2f();
min_xyz = max_xyz = vertex.get_data3f();
} else {
const LVecBase2f &uv = texcoord.get_data2f();
const LVecBase3f &xyz = vertex.get_data3f();
min_uv[0] = min(min_uv[0], uv[0]);
max_uv[0] = max(max_uv[0], uv[0]);
min_uv[1] = min(min_uv[1], uv[1]);
max_uv[1] = max(max_uv[1], uv[1]);
min_xyz[0] = min(min_xyz[0], xyz[0]);
max_xyz[0] = max(max_xyz[0], xyz[0]);
min_xyz[1] = min(min_xyz[1], xyz[1]);
max_xyz[1] = max(max_xyz[1], xyz[1]);
min_xyz[2] = min(min_xyz[2], xyz[2]);
max_xyz[2] = max(max_xyz[2], xyz[2]);
if (texcoord.has_column() && vertex.has_column()) {
bool found_any = false;
for (int pi = 0; pi < qpgeom->get_num_primitives(); ++pi) {
const qpGeomPrimitive *primitive = qpgeom->get_primitive(pi);
for (int vi = 0; vi < primitive->get_num_vertices(); ++vi) {
int vert = primitive->get_vertex(vi);
texcoord.set_vertex(vert);
vertex.set_vertex(vert);
if (!found_any) {
min_uv = max_uv = texcoord.get_data2f();
min_xyz = max_xyz = vertex.get_data3f();
} else {
const LVecBase2f &uv = texcoord.get_data2f();
const LVecBase3f &xyz = vertex.get_data3f();
min_uv[0] = min(min_uv[0], uv[0]);
max_uv[0] = max(max_uv[0], uv[0]);
min_uv[1] = min(min_uv[1], uv[1]);
max_uv[1] = max(max_uv[1], uv[1]);
min_xyz[0] = min(min_xyz[0], xyz[0]);
max_xyz[0] = max(max_xyz[0], xyz[0]);
min_xyz[1] = min(min_xyz[1], xyz[1]);
max_xyz[1] = max(max_xyz[1], xyz[1]);
min_xyz[2] = min(min_xyz[2], xyz[2]);
max_xyz[2] = max(max_xyz[2], xyz[2]);
}
}
}
}