UInt32 ParticleBSPTree::doBuild(std::vector<Int32>::iterator begin, std::vector<Int32>::iterator end, UInt32 nodeindex, GeoPositionsPtr pos) { // reached a leaf? if(begin + 1 == end) { _tree[nodeindex].setValue(*begin); return nodeindex + 1; } // find the bounding volume of the group BoxVolume b; Pnt3f p; b.setEmpty(); for(std::vector<Int32>::iterator i = begin; i != end; ++i) { pos->getValue(p,*i); b.extendBy(p); } // find the axis with the longest extension Vec3f d = b.getMax() - b.getMin(); UInt8 axis = ParticleBSPNode::X; Real32 maxval = d[0]; if(d[1] > maxval) { axis = ParticleBSPNode::Y; maxval = d[1]; } if(d[2] > maxval) { axis = ParticleBSPNode::Z; maxval = d[2]; } // sort in that axis ParticleCompare comp(pos, axis); std::sort(begin,end,comp); // find median value std::vector<Int32>::iterator mid = begin + (end - begin) / 2; Pnt3f p2; pos->getValue(p ,*mid); pos->getValue(p2,(*mid)-1); _tree[nodeindex].setSplit(axis, (p[axis] + p2[axis]) / 2.f); return osgMax( doBuild(begin, mid, nodeindex * 2 , pos), doBuild( mid, end, nodeindex * 2 + 1, pos) ); }
void FaceSpatializeIndexed<BasicTraits>::CategoryRaw::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { GeoPositions3f::StoredFieldType* p = m_coord->getFieldPtr(); GeoNormals3f::StoredFieldType* n = m_normal->getFieldPtr(); //GeoIndicesUI32::StoredFieldType* i = m_index->getFieldPtr(); // find offset of positions and normals in the new geometry u32 i, k; m_offsetIt = m_offset.find(face.getGeometry()); if (m_offsetIt == m_offset.end()) { // insert new offsets entry into map HashMapPair offsetPair = m_offset.insert(HashMap::value_type(face.getGeometry(), quad())); m_offsetIt = offsetPair.first; m_offsetIt->second.position = m_coord->size(); GeoPositionsPtr faceP = m_original.getPositions(); addRefCP(faceP); for (k=0; k<faceP->getSize(); ++k) { p->addValue(faceP->getValue(k)); } if (m_hasNormal) { m_offsetIt->second.normal = m_normal->size(); GeoNormalsPtr faceN = m_original.getNormals(); addRefCP(faceN); for (k=0; k<faceN->getSize(); ++k) { n->addValue(faceN->getValue(k)); } subRefCP(faceN); } subRefCP(faceP); } // insert indices if (face.getLength() == 3) { for (k=0; k<3; ++k) { m_index->insertValue(face.getPositionIndex(k)+m_offsetIt->second.position, m_quadOffset++); i = 1; if (m_hasNormal) { m_index->insertValue(face.getNormalIndex(k)+m_offsetIt->second.normal, m_quadOffset++); ++i; } for (; i<m_indexStride; ++i) { m_index->insertValue(0, m_quadOffset++); } } } else { for (k=0; k<4; ++k) { m_index->addValue(face.getPositionIndex(k)+m_offsetIt->second.position); i = 1; if (m_hasNormal) { m_index->addValue(face.getNormalIndex(k)+m_offsetIt->second.normal); ++i; } for (; i<m_indexStride; ++i) { m_index->addValue(0); } } } }
static NodePtr makePerturbedUniform (UInt16 numSubdiv, Real32 radius, Real32 rate = 0.1f) { static Real32 factor = 1.1f; NodePtr sphereNode = makeSphere(numSubdiv, radius); GeometryPtr sphere = GeometryPtr::dcast(sphereNode->getCore()); GeoPositionsPtr points = sphere->getPositions(); beginEditCP(points); for (UInt32 i=0; i<points->size(); ++i) { Real32 random = (rand()/Real32(RAND_MAX)); if (random <= rate) { points->setValue(factor*points->getValue(i), i); } } endEditCP(points); NodePtr node = Node::create(); beginEditCP(node); node->setCore(Transform::create()); node->addChild(sphereNode); endEditCP(node); return node; }
// redraw the window void display( void ) { // create the matrix Matrix m; Real32 t = glutGet(GLUT_ELAPSED_TIME ); m.setTransform(Quaternion( Vec3f(0,1,0), t / 1000.f)); // set the transform's matrix beginEditCP(trans, Transform::MatrixFieldMask); { trans->setMatrix(m); } endEditCP (trans, Transform::MatrixFieldMask); /* Manipulate the geometry. The OpenSG geometry structure is pretty flexible. The disadvantage of all this flexibility is that it can be hard to write generic tools, as pretty much all the used types can be one of a number of variants. To simplify that, every kind of GeoProperty has a generic type, e.g. the generic type for positions is Pnt3f, for colors it's Color3f. No matter the internal data representation looks like, all GeoProperties have the generic interface. As does the abstract parent class of every kind of property. Thus it's possible to access the data of an arbitrary geometry using the generic interface. */ // note that this is the abstract parent class, it doesn't have a specific // type GeoPositionsPtr pos = geo->getPositions(); beginEditCP(pos); for(UInt32 i = 0; i < pos->getSize(); i++) { Pnt3f p; pos->getValue(p, i); p[0] += osgsin(t / 300) * p[1] / 100; p[1] += osgsin(t / 300) * p[2] / 100; p[2] += osgsin(t / 300) * p[0] / 100; pos->setValue(p, i); } endEditCP (pos); // right now the geometry doesn't notice changes to the properties, it has // to be notified explicitly beginEditCP(geo, Geometry::PositionsFieldMask); endEditCP (geo, Geometry::PositionsFieldMask); mgr->redraw(); }
void ParticleBSPTree::build(Particles *core) { _tree.clear(); if(core == NULL) { FWARNING(("ParticleBSP::build: no core!!\n")); return; } const GeoPositionsPtr pos = core->getPositions(); if(pos == NullFC) return; const MFInt32 *indices = core->getMFIndices(); // 1. create list for particles std::vector<Int32> order; order.reserve(pos->getSize()); for(UInt32 i = 0; i < pos->getSize(); ++i ) { if(indices->size() == pos->getSize()) { order.push_back((*indices)[i]); } else { order.push_back(i); } } // reserve mem for tree _tree.resize(osgnextpower2(order.size()) * 2); // 2. recursively build the tree UInt32 nnodes = doBuild(order.begin(), order.end(), 1, pos); // 3. remove the unneeded elements from the end if(nnodes < _tree.size()) _tree.erase( _tree.begin() + nnodes, _tree.end()); // done }
void CParticleEmitter::Update( Real32 i_rTime, Real32 i_rDeltaTime, bool i_bSimulate ) { const Real64 rInvDesiredUpdatesPerSecond = 1.0f / (Real64)m_pParent->rGetDesiredUpdatesPerSecond(); m_rEmissionRemainder += rGetEmittedParticles( i_rTime ) * rInvDesiredUpdatesPerSecond; UInt32 iEmittedParticles = (UInt32)m_rEmissionRemainder; m_rEmissionRemainder -= iEmittedParticles; GeoPositionsPtr pPos = NullFC; GeoColorsPtr pCols = NullFC; MFVec3f *pSizes = 0; if( !i_bSimulate ) { beginEditCP( m_pDrawableParticles ); pPos = m_pDrawableParticles->getPositions(); beginEditCP( pPos ); pCols = m_pDrawableParticles->getColors(); beginEditCP( pCols ); pSizes = m_pDrawableParticles->getMFSizes(); pPos->clear(); pCols->clear(); pSizes->clear(); } particle *pCurParticle = m_pParticles; for( UInt32 i = 0; i < m_iNumParticles; ++i, ++pCurParticle ) { pCurParticle->position += m_nextMovement; bool bParticleOkay = m_pParticleType->bUpdateParticle( *pCurParticle, i_rDeltaTime, pPos, pCols, pSizes ); if( !bParticleOkay && iEmittedParticles > 0 ) { bParticleOkay = bSpawnParticle( *pCurParticle, i_rTime, m_pParent->RandomSpawnPoint() ); if( bParticleOkay ) { m_pParticleType->bUpdateParticle( *pCurParticle, i_rDeltaTime, pPos, pCols, pSizes ); --iEmittedParticles; } } } m_nextMovement = Vec3f( 0.0f, 0.0f, 0.0f ); // reset movement vector if( !i_bSimulate ) { endEditCP( pCols ); endEditCP( pPos ); endEditCP( m_pDrawableParticles ); } }
void FaceSpatialize<BasicTraits>::CategoryRaw::addData (OpenSGFaceBase<OpenSGTraits>* node, const FaceIterator& face) { GeoPositions3f::StoredFieldType* p = m_coord->getFieldPtr(); GeoNormals3f::StoredFieldType* n = m_normal->getFieldPtr(); //GeoIndicesUI32::StoredFieldType* i = m_index->getFieldPtr(); GeoPositionsPtr faceP = node->getPositions(); addRefCP(faceP); u32 k; for (k=0; k<faceP->getSize(); ++k) { p->addValue(faceP->getValue(k)); if (face.getLength()==3) { m_index->insertValue(p->size()-1, m_quadOffset++); } else { m_index->addValue(p->size()-1); } } if (!m_hasNormal) { #if 1 Vec3f p0(faceP->getValue(0)); Vec3f p1(faceP->getValue(1)); Vec3f p2(faceP->getValue(2)); p2 -= p1; p0 -= p1; if (m_ccw) { p0.crossThis(p2); p0.normalize(); n->addValue(p0); } else { p2.crossThis(p0); p2.normalize(); n->addValue(p2); } #endif } else { // per-vertex normals or per-face normals GeoNormalsPtr faceN = node->getNormals(); addRefCP(faceN); for (k=0; k<faceN->getSize(); ++k) { n->addValue(faceN->getValue(k)); } subRefCP(faceN); } subRefCP(faceP); }
static NodePtr makePerturbedAll (UInt16 numSubdiv, Real32 radius, Real32 stdDeviation = 0.1f) { NodePtr sphereNode = makeSphere(numSubdiv, radius); GeometryPtr sphere = GeometryPtr::dcast(sphereNode->getCore()); GeoPositionsPtr points = sphere->getPositions(); beginEditCP(points); for (UInt32 i=0; i<points->size(); ++i) { Real32 factor = 1.0f + stdDeviation * (rand()/Real32(RAND_MAX) - 0.5f); points->setValue(factor*points->getValue(i), i); } endEditCP(points); NodePtr node = Node::create(); beginEditCP(node); node->setCore(Transform::create()); node->addChild(sphereNode); endEditCP(node); return node; }
Action::ResultE OOCOSGFeeder::enter(NodePtr& node) { GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if(geo == NullFC) return Action::Continue; GeoPositionsPtr pos = geo->getPositions(); UInt32 pntindexbase; if(_poss.find(pos) != _poss.end()) { pntindexbase = _poss[pos]; pos = NullFC; } else { pntindexbase = _pntindexbase; _poss[pos] = _pntindexbase; _pntindexbase += pos->getSize(); } UInt32 matind = MaterialPool::addMaterial(geo->getMaterial()); if(pos != NullFC) { if(_pfunc != NULL) { Pnt3f p; UInt32 s = pos->getSize(); for(UInt32 i = 0; i < s; ++i) { if(_npts != 0) { ++_pntprog; Real32 prog = _pntprog / (Real32)_npts; if(prog > _nextpntprog) { PLOG << _nextpntprog * 100 << "%.."; _nextpntprog += 0.1; } } pos->getValue(p, i); _pfunc(_rec, p); } } } if(_tfunc != NULL) { TriangleIterator it, end = geo->endTriangles(); for(it = geo->beginTriangles(); it != end; ++it) { if(_ntris != 0) { ++_triprog; Real32 prog = _triprog / (Real32)_ntris; if(prog > _nexttriprog) { PLOG << _nexttriprog * 100 << "%.."; _nexttriprog += 0.1; } } _tfunc(_rec, it.getPositionIndex(0) + pntindexbase, it.getPositionIndex(1) + pntindexbase, it.getPositionIndex(2) + pntindexbase, matind); } } return Action::Continue; }