// Find a boundingBox in the node hierarchy. // Return: use bounding box for collision? bool BulletNifLoader::findBoundingBox(const Nif::Node* node) { if (node->hasBounds) { mShape->mCollisionBoxHalfExtents = node->boundXYZ; mShape->mCollisionBoxTranslate = node->boundPos; if (node->flags & Nif::NiNode::Flag_BBoxCollision) { return true; } } const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node); if(ninode) { const Nif::NodeList &list = ninode->children; for(size_t i = 0;i < list.length();i++) { if(!list[i].empty()) { bool found = findBoundingBox (list[i].getPtr()); if (found) return true; } } } return false; }
/** * @brief Removes a Surface from this Cell's container of bounding Surfaces. * @param surface a pointer to the Surface to remove */ void Cell::removeSurface(Surface* surface) { if (_surfaces.find(surface->getId()) != _surfaces.end()) _surfaces.erase(surface->getId()); findBoundingBox(); }
ParticleNeighborSearcher::ParticleNeighborSearcher(std::vector<Particle>* const particles, const float& smoothRadius) : mParticles(particles), mSmoothRadius(smoothRadius) { vec3 cellsize(mSmoothRadius); vec3 bboxmin, bboxmax; findBoundingBox(bboxmin, bboxmax); mNeighborSearchGrid.initialize(cellsize, bboxmin, bboxmax); }
/** * @brief Insert a Surface into this Cell's container of bounding Surfaces. * @param halfspace the Surface halfspace (+/-1) * @param surface a pointer to the Surface */ void Cell::addSurface(int halfspace, Surface* surface) { if (halfspace != -1 && halfspace != +1) log_printf(ERROR, "Unable to add surface %d to cell %d since the halfspace" " %d is not -1 or 1", surface->getId(), _id, halfspace); surface_halfspace* new_surf_half = new surface_halfspace; new_surf_half->_surface = surface; new_surf_half->_halfspace = halfspace; _surfaces[surface->getId()] = *new_surf_half; findBoundingBox(); }
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif) { mShape = new Resource::BulletShape; mCompoundShape.reset(); mStaticMesh.reset(); mAvoidStaticMesh.reset(); if (nif.numRoots() < 1) { warn("Found no root nodes in NIF."); return mShape; } Nif::Record *r = nif.getRoot(0); assert(r != nullptr); Nif::Node *node = dynamic_cast<Nif::Node*>(r); if (node == nullptr) { warn("First root in file was not a node, but a " + r->recName + ". Skipping file."); return mShape; } if (findBoundingBox(node)) { std::unique_ptr<btCompoundShape> compound (new btCompoundShape); std::unique_ptr<btBoxShape> boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents))); btTransform transform = btTransform::getIdentity(); transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); compound->addChildShape(transform, boxShape.get()); boxShape.release(); mShape->mCollisionShape = compound.release(); return mShape; } else { bool autogenerated = hasAutoGeneratedCollision(node); // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). // assume all nodes in the file will be animated const auto filename = nif.getFilename(); const bool isAnimated = pathFileNameStartsWithX(filename); handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated); if (mCompoundShape) { if (mStaticMesh) { btTransform trans; trans.setIdentity(); std::unique_ptr<btCollisionShape> child(new Resource::TriangleMeshShape(mStaticMesh.get(), true)); mCompoundShape->addChildShape(trans, child.get()); child.release(); mStaticMesh.release(); } mShape->mCollisionShape = mCompoundShape.release(); } else if (mStaticMesh) { mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true); mStaticMesh.release(); } if (mAvoidStaticMesh) { mShape->mAvoidCollisionShape = new Resource::TriangleMeshShape(mAvoidStaticMesh.get(), false); mAvoidStaticMesh.release(); } return mShape; } }
//-------------------------------------------------------------- void testApp::keyPressed(int key){ switch(key) { case 'M': case 'm': if(cam.getMouseInputEnabled()) cam.disableMouseInput(); else cam.enableMouseInput(); break; case 'F': case 'f': ofToggleFullscreen(); break; case 'T': case 't': state=STATE_TENT; cam.enableMouseInput(); break; case 'C': case 'c': state=STATE_MODEL; cam.enableMouseInput(); break; case 'S': case 's': state = STATE_SCREEN; cam.disableMouseInput(); if (currentScreen>=screens.size()) { currentScreen = 0; } break; case 'P': case 'p': bProject = !bProject; break; case 'Q': case 'q': bScreen = !bScreen; break; case 'G': case 'g': cam.begin(); ofSaveMatrices(ofToDataPath("matrices.txt")); cam.end(); break; default: break; } switch (state) { case STATE_TENT: switch(key) { case '1': case '2': case '3': case '4': { int i = key-'1'; if (selection[i].second) { selection[i].second = false; } else { selection[i].first = choice; selection[i].second = true; } } break; case 'A': case 'a': { int count = 0; for (int i=0; i<selection.size(); i++) { count += selection[i].second ? 1 : 0; } if (count>=3) { screen s; vector<ofVec3f> input; for (int i=0; i<selection.size(); i++) { if (selection[i].second) { s.indices.push_back(selection[i].first); input.push_back(tentMesh.getVerticesPointer()[selection[i].first]); } } vector<ofVec3f> bb = findBoundingBox(input); screenCoordinateSystem(bb, s.origin, s.xVec, s.yVec); //s.vertices = findScreenCorners(bb, ofGetWidth(), ofGetHeight(), scale); s.index = selection[0].first; screens.push_back(s); save(); } } break; case 'R': case 'r': { int ref = choice; if (selection[0].second) { ref = selection[0].first; } for (vector<screen>::iterator siter=screens.begin(); siter!=screens.end(); siter++) { if (siter->index == ref) { screens.erase(siter); save(); break; } } } break; case 'D': case 'd': { for (int i=0; i<selection.size(); i++) { selection[i].second = false; } } break; } break; case STATE_MODEL: switch(key) { case 'L': case 'l': bTent=!bTent; bOrigin = false; break; case 'O': case 'o': bOrigin=!bOrigin; origin = choice; break; case 'A': case 'a': if (bOrigin) { tent t; t.first = origin; t.second = choice; tents.push_back(t); bOrigin = false; save(); } break; case 'R': case 'r': { int ref = choice; for (vector<tent >::iterator titer=tents.begin(); titer!=tents.end(); titer++) { if (titer->first == ref) { tents.erase(titer); save(); break; } } } break; default: break; } break; case STATE_SCREEN: switch (key) { case 'R': case 'r': for (vector<ofRectangle>::iterator iter = rects.begin(); iter!=rects.end(); iter++) { if (iter->inside(ofVec2f(ofGetMouseX(),ofGetMouseY()))) { rects.erase(iter); save(); break; } } break; case OF_KEY_LEFT: currentScreen = (currentScreen-1+screens.size()) % screens.size(); break; case OF_KEY_RIGHT: currentScreen = (currentScreen+1) % screens.size(); break; default: break; } break; default: break; } }
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr& nif) { mShape = new Resource::BulletShape; mCompoundShape = NULL; mStaticMesh = NULL; if (nif->numRoots() < 1) { warn("Found no root nodes in NIF."); return mShape; } Nif::Record *r = nif->getRoot(0); assert(r != NULL); Nif::Node *node = dynamic_cast<Nif::Node*>(r); if (node == NULL) { warn("First root in file was not a node, but a " + r->recName + ". Skipping file."); return mShape; } if (findBoundingBox(node)) { std::unique_ptr<btCompoundShape> compound (new btCompoundShape); btBoxShape* boxShape = new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents)); btTransform transform = btTransform::getIdentity(); transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); compound->addChildShape(transform, boxShape); mShape->mCollisionShape = compound.release(); return mShape; } else { bool autogenerated = hasAutoGeneratedCollision(node); bool isAnimated = false; // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). // assume all nodes in the file will be animated std::string filename = nif->getFilename(); size_t slashpos = filename.find_last_of("/\\"); if (slashpos == std::string::npos) slashpos = 0; if (slashpos+1 < filename.size() && (filename[slashpos+1] == 'x' || filename[slashpos+1] == 'X')) { isAnimated = true; } handleNode(node, 0, autogenerated, isAnimated, autogenerated); if (mCompoundShape) { mShape->mCollisionShape = mCompoundShape; if (mStaticMesh) { btTransform trans; trans.setIdentity(); mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true)); } } else if (mStaticMesh) mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true); return mShape; } }