//*********************************************************************************************** bool CParticleWorkspace::CNode::loadPS() { nlassert(_WS); // manually load the PS shape (so that we can deal with exceptions) NL3D::CShapeStream ss; NLMISC::CIFile inputFile; // collapse name inputFile.open(getFullPath()); ss.serial(inputFile); std::auto_ptr<NL3D::CShapeBank> sb(new NL3D::CShapeBank); std::string shapeName = NLMISC::CFile::getFilename(_RelativePath); sb->add(shapeName, ss.getShapePointer()); NL3D::CShapeBank *oldSB = NL3D::CNELU::Scene->getShapeBank(); NL3D::CNELU::Scene->setShapeBank(sb.get()); NL3D::CTransformShape *trs = NL3D::CNELU::Scene->createInstance(shapeName); if (!trs) { NL3D::CNELU::Scene->setShapeBank(oldSB); return false; } NL3D::CParticleSystemModel *psm = dynamic_cast<NL3D::CParticleSystemModel *>(trs); if (!psm) { // Not a particle system NL3D::CNELU::Scene->deleteInstance(trs); return false; } NL3D::CNELU::Scene->setShapeBank(oldSB); setup(*psm); unload(); // commit new values _PS = psm->getPS(); _PSM = psm; _ShapeBank = sb.release(); _Modified = false; return true; }
/** Load and compute the bbox of the models that are contained in a given instance group * \return true if the computed bbox is valid */ static void computeIGBBox(const NL3D::CInstanceGroup &ig, CLightingBBox &result, TShapeMap &shapeMap) { result = CLightingBBox(); // starts with void result bool firstBBox = true; /// now, compute the union of all bboxs for (CInstanceGroup::TInstanceArray::const_iterator it = ig._InstancesInfos.begin(); it != ig._InstancesInfos.end(); ++it) { CLightingBBox currBBox; bool validBBox = false; /// get the bbox from file or from map if (shapeMap.count(it->Name)) // already loaded ? { currBBox = shapeMap[it->Name]; validBBox = true; } else // must load the shape to get its bbox { std::string shapePathName; std::string toLoad = it->Name; if (getExt(toLoad).empty()) toLoad += ".shape"; shapePathName = NLMISC::CPath::lookup(toLoad, false, false); if (shapePathName.empty()) { nlwarning("Unable to find shape %s", it->Name.c_str()); } else { CIFile shapeInputFile; if (shapeInputFile.open (shapePathName.c_str())) { NL3D::CShapeStream shapeStream; try { shapeStream.serial (shapeInputFile); // NB Nico : // Deal with water shape -> their 'Receiving' box is set to 'void' // this prevent the case where a huge surface of water will cause the zone it is attached to (the 'Zone' // field in the villages sheets) to load all the zones that the water surface cover. (This caused // an 'out of memory error' in the zone lighter due to too many zone being loaded) // FIXME : test for water case hardcoded for now CWaterShape *ws = dynamic_cast<CWaterShape *>(shapeStream.getShapePointer()); if (ws) { CAABBox bbox; shapeStream.getShapePointer()->getAABBox(bbox); currBBox.OccludingBox = CPotentialBBox(bbox); // occluding box is used, though the water shape // doesn't cast shadow -> the tiles flag ('above', 'intersect', 'below water') // are updated inside the zone_lighter currBBox.ReceivingBox.IsVoid = true; // no lighted by the zone lighter !!! currBBox.removeVoid(); shapeMap[it->Name] = currBBox; } else { CAABBox bbox; shapeStream.getShapePointer()->getAABBox(bbox); currBBox.OccludingBox = CPotentialBBox(bbox); currBBox.ReceivingBox = CPotentialBBox(bbox); currBBox.removeVoid(); shapeMap[it->Name] = currBBox; } validBBox = true; } catch (NLMISC::Exception &e) { nlwarning("Error while loading shape %s. \n\t Reason : %s ", it->Name.c_str(), e.what()); } } else { nlwarning("Unable to open shape file %s to get its bbox", it->Name.c_str()); } } } if (validBBox) { /// build the model matrix NLMISC::CMatrix mat; mat.scale(it->Scale); NLMISC::CMatrix rotMat; rotMat.setRot(it->Rot); mat = rotMat * mat; mat.setPos(it->Pos); /// transform the bbox currBBox.transform(mat); currBBox.removeVoid(); if (firstBBox) { result = currBBox; firstBBox = false; } else // add to previous one { result.makeUnion(currBBox); } } } }