Hi Robert I see no loss in removing more parts from the basic viewer for this demo code; I was just doing the minimal changes to produce a decent demo. I will try to simplify the demo soon.
Moving implementation details also sounds wise, are you doing this? If not my attempt to move the implementation is attached. Geoff ----- Original Message ----- From: Max Bandazian To: OpenSceneGraph Submissions Sent: Saturday, August 01, 2009 6:42 PM Subject: Re: [osg-submissions] osg::Group::removeChildren performance The algorithm copies things from the end of the vector into the locations of the elements to be deleted, and then shortens the vector by that amount. So if your vector is a, b, c and you want to remove 'a', first c gets copied into a's spot (c, b, c), then the vector is resized (c, b). I guess that would break Switch nodes etc. Normally it would be fine with me if this doesn't make it into osg, but the use of friends in osg::Node means that it's impossible to correctly reimplement osg::Group::removeChildren without changing the Node header. Maybe it could be added as an osg::UnorderedGroup, or the current osg::Group could become osg::OrderedGroup, etc. - Max On Fri, Jul 31, 2009 at 5:02 PM, Thrall, Bryan <[email protected]> wrote: Max Bandazian wrote on Friday, July 31, 2009 12:54 PM: > if (_children.size() == numChildrenToRemove) > { > _children.clear(); > } > else > { > int numThingsToCopy = std::min(numChildrenToRemove, > _children.size() - numChildrenToRemove); > std::copy(_children.end() - numThingsToCopy, _children.end(), > _children.begin() + pos); _children.resize(_children.size() - > numChildrenToRemove); } > > With this change, removing the 30,000 nodes takes less than 1 second. It does > change the semantics of removing children from a group, in that the children > will be in a different order rather than just having their index changed. In > my opinion it's worth it for the performance gain. That sounds pretty nice, but I must be missing something, because that code looks like it does not change the order of the children. What's the down side again? -- Bryan Thrall FlightSafety International [email protected] _______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org ------------------------------------------------------------------------------ _______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
InertiaVisitor
Description: Binary data
#include <osgUtil/InertiaVisitor>
// included as separate file to ensure that InertiaVisitor is compiled into
// libraries.
void InertiaVisitor::apply(osg::Geode& geode) {
osg::NodePath nodePath = getNodePath();
unsigned int i;
osg::Matrix totalmat; // accumulated matrix above this point
for(i=0; i<nodePath.size()-1; ++i)
{
osg::Transform* transform = nodePath[i]->asTransform();
if (transform) { // concatenate to totalmat.
transform->computeLocalToWorldMatrix(totalmat, this);
}
}
for (unsigned int i=0; i<geode.getNumDrawables(); i++) {
osg::Geometry *dr=dynamic_cast<osg::Geometry
*>(geode.getDrawable(i));
if (dr) {
// 200409 use ComputeInertiaTriangleFunctor to
calculate volume, MI etc
osg::TriangleFunctor<ComputeInertiaTriangleFunctor>
inert;
inert.setMatrix(totalmat);
dr->accept(inert);
_m+=inert.getVolume();
_Cx+=inert.getCx();
_Cy+=inert.getCy();
_Cz+=inert.getCz();
_xx+=inert.getixx();
_yy+=inert.getiyy();
_zz+=inert.getizz();
_zx+=inert.getizx();
_yx+=inert.getiyx();
_zy+=inert.getizy();
Area+=inert.getArea();
ntris+=inert.getntris();
osg::Vec2 xr=inert.getXrange();
if (xr.x()<xmin) xmin=xr.x();
if (xr.y()>xmax) xmax=xr.y();
osg::Vec2 yr=inert.getYrange();
if (yr.x()<ymin) ymin=yr.x();
if (yr.y()>ymax) ymax=yr.y();
osg::Vec2 zr=inert.getZrange();
if (zr.x()<zmin) zmin=zr.x();
if (zr.y()>zmax) zmax=zr.y();
}
}
finish(); // construct the actual Inertia from the partial sums.
}
/**********************************************************************
from Reference 1.
Add the contribution of a triangle to the mass properties.
Call this method for each one of the mesh's triangles.
The order of vertices must be such that their determinant is positive
when the origin lies on the inner side of this facet's plane.
**********************************************************************/
void ComputeInertiaTriangleFunctor::AddTriangleContribution(const osg::Vec3
v1,const osg::Vec3 v2,const osg::Vec3 v3)
{
double x1=v1.x(), y1=v1.y(), z1=v1.z(); // Triangle's vertex 1
double x2=v2.x(), y2=v2.y(), z2=v2.z(); // Triangle's vertex 2
double x3=v3.x(), y3=v3.y(), z3=v3.z(); // Triangle's vertex 3
// Signed volume of this tetrahedron.
double v = x1*y2*z3 + y1*z2*x3 + x2*y3*z1 -
(x3*y2*z1 + x2*y1*z3 + y3*z2*x1);
// Contribution to the mass
_m += v;
// contribution to area; half base*height
area+=((v2-v1)^(v3-v2)).length()/2.0;
// Contribution to the centroid
double x4 = x1 + x2 + x3; _Cx += (v * x4);
double y4 = y1 + y2 + y3; _Cy += (v * y4);
double z4 = z1 + z2 + z3; _Cz += (v * z4);
// Contribution to moment of inertia monomials
_xx += v * (x1*x1 + x2*x2 + x3*x3 + x4*x4);
_yy += v * (y1*y1 + y2*y2 + y3*y3 + y4*y4);
_zz += v * (z1*z1 + z2*z2 + z3*z3 + z4*z4);
_yx += v * (y1*x1 + y2*x2 + y3*x3 + y4*x4);
_zx += v * (z1*x1 + z2*x2 + z3*x3 + z4*x4);
_zy += v * (z1*y1 + z2*y2 + z3*y3 + z4*y4);
// NB x4*x4 = x1*x1+x1*x2+x1*x3 + x2*x1 + x2*x2 + x2*x3+x3*x1+x3*x2+x3*x3....
ntris++;
// get range of coordinates used in triangles
if (x1<xmin) xmin=x1;
if (x2<xmin) xmin=x2;
if (x3<xmin) xmin=x3;
if (x1>xmax) xmax=x1;
if (x2>xmax) xmax=x2;
if (x3>xmax) xmax=x3;
// also Y coordinate
if (y1<ymin) ymin=y1;
if (y2<ymin) ymin=y2;
if (y3<ymin) ymin=y3;
if (y1>ymax) ymax=y1;
if (y2>ymax) ymax=y2;
if (y3>ymax) ymax=y3;
// and Z coordinate
if (z1<zmin) zmin=z1;
if (z2<zmin) zmin=z2;
if (z3<zmin) zmin=z3;
if (z1>zmax) zmax=z1;
if (z2>zmax) zmax=z2;
if (z3>zmax) zmax=z3;
}
void ComputeInertiaTriangleFunctor::zeroProperties() { // zero inertia
component sums.
// automatically zeroed at creation time, call if reused.
_m=0; // Mass (times 6 to save divisions)
_Cx=0; _Cy=0; _Cz=0; // Centroid
_xx=0; _yy=0; _zz=0; _yx=0; _zx=0; _zy=0; // Moment of inertia tensor
ntris = 0; // number of triangles modelling the drawable
area=0;
xmin=1.e32,xmax=-1.e32; // initialise range of coordiantes
ymin=1.e32,ymax=-1.e32;
zmin=1.e32,zmax=-1.e32;
}
/**********************************************************************
>From ref 1 with minor improvements to allow reuse.
This method is called to obtain the results.
code from http://jgt.akpeters.com/papers/Kallay06/Moment_of_Inertia.cpp
As published method GetResults modifies the internal data; calling it again
would return
incorrect results. Modified to prevent this by using a local variable.
After calling this routine the results are stored in _Ixx etc
**********************************************************************/
void InertiaVisitor::GetResults( // returns m, Cx etc
double & m, // Total mass
double & Cx, double & Cy, double & Cz, // Centroid
double & Ixx, double & Iyy, double & Izz, // Moment of inertia
// diagonal entries
double & Iyx, double & Izx, double & Izy) // Moment of inertia
// mixed entries
const { // NB const ensures that the aprtial sums are not damaged.
// Centroid.
// can now be called multiple times as does not modify routine.
if (_m!=0) { // The case _m = 0 means zero volume.
double r = 1.0 / (4 * _m);
Cx = _Cx * r;
Cy = _Cy * r;
Cz = _Cz * r;
// Mass
m = _m / 6;
// Moment of inertia about the centroid.
r = 1.0 / 120;
Iyx = _yx * r - m * Cy*Cx;
Izx = _zx * r - m * Cz*Cx;
Izy = _zy * r - m * Cz*Cy;
// 110709 protect internal sums
double _xxt = _xx * r - m * Cx*Cx;
double _yyt = _yy * r - m * Cy*Cy;
double _zzt = _zz * r - m * Cz*Cz;
Ixx = _yyt + _zzt;
Iyy = _zzt + _xxt;
Izz = _xxt + _yyt;
}
}
void InertiaVisitor::zeroInertiaTensor() { // zero inertia COMPONENTS at start
of write
// automatically zeroed at creation time, call if reused.
_m=0; // Mass
_Cx=0; _Cy=0; _Cz=0; // Centroid
_xx=0; _yy=0; _zz=0; _yx=0; _zx=0; _zy=0; // Moment of inertia tensor
xmin=1.e32,xmax=-1.e32; // rezero range of coordiantes
ymin=1.e32,ymax=-1.e32;
zmin=1.e32,zmax=-1.e32;
Area=0;
ntris = 0; // number of triangles modelling the object
}
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
