📄 ac3d.cpp
字号:
else if (flags & SurfaceShaded) { if (flags & SurfaceTwoSided) { if (!smoothDoubleSurfaceBin.valid()) { smoothDoubleSurfaceBin = new SurfaceBin(flags, vertexSet); } return smoothDoubleSurfaceBin.get(); } else { if (!smoothSingleSurfaceBin.valid()) { smoothSingleSurfaceBin = new SurfaceBin(flags, vertexSet); } return smoothSingleSurfaceBin.get(); } } else { if (flags & SurfaceTwoSided) { if (!flatDoubleSurfaceBin.valid()) { flatDoubleSurfaceBin = new SurfaceBin(flags, vertexSet); } return flatDoubleSurfaceBin.get(); } else { if (!flatSingleSurfaceBin.valid()) { flatSingleSurfaceBin = new SurfaceBin(flags, vertexSet); } return flatSingleSurfaceBin.get(); } } } void finalize(osg::Group* group, const MaterialData& material, const TextureData& textureData) { if (lineBin.valid()) { group->addChild(lineBin->finalize(material, textureData)); } if (smoothDoubleSurfaceBin.valid()) { group->addChild(smoothDoubleSurfaceBin->finalize(material, textureData)); } if (smoothSingleSurfaceBin.valid()) { group->addChild(smoothSingleSurfaceBin->finalize(material, textureData)); } if (flatDoubleSurfaceBin.valid()) { group->addChild(flatDoubleSurfaceBin->finalize(material, textureData)); } if (flatSingleSurfaceBin.valid()) { group->addChild(flatSingleSurfaceBin->finalize(material, textureData)); } }private: osg::ref_ptr<LineBin> lineBin; osg::ref_ptr<SurfaceBin> flatDoubleSurfaceBin; osg::ref_ptr<SurfaceBin> flatSingleSurfaceBin; osg::ref_ptr<SurfaceBin> smoothDoubleSurfaceBin; osg::ref_ptr<SurfaceBin> smoothSingleSurfaceBin;};osg::Node*readObject(std::istream& stream, FileData& fileData, const osg::Matrix& parentTransform, TextureData textureData){ // most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right! // The transform configured in this current object level osg::Matrix transform; // The vertex pool in this object osg::ref_ptr<VertexSet> vertexSet = new VertexSet; osg::ref_ptr<osg::Group> group = new osg::Group; group->setDataVariance(osg::Object::STATIC); osg::Vec2 textureOffset(0, 0); osg::Vec2 textureRepeat(1, 1); float creaseAngle = 61; unsigned objectType = ObjectTypeGroup; while (!stream.eof() && stream.good()) { std::string token; stream >> token; if (token == "MATERIAL") { MaterialData mat; mat.readMaterial(stream); fileData.addMaterial(mat); } else if (token == "OBJECT") { std::string type; stream >> type; if (type == "group") objectType = ObjectTypeGroup; else if (type == "light") objectType = ObjectTypeLight; else if (type == "world") objectType = ObjectTypeGroup; else objectType = ObjectTypeNormal; } else if (token == "crease") { stream >> creaseAngle; } else if (token == "data") { int len; stream >> len; std::vector<char> tmp(len); stream.read(&(tmp[0]), len); } else if (token == "name") { group->setName(readString(stream)); } else if (token == "texture") { // read the texture name std::string texname = readString(stream); // strip absolute paths if (texname[0] == '/' || isalpha(texname[0]) && texname[1] == ':') { std::string::size_type p = texname.rfind('\\'); if (p != std::string::npos) texname = texname.substr(p+1, std::string::npos); p = texname.rfind('/'); if (p != std::string::npos) texname = texname.substr(p+1, std::string::npos); } textureData = fileData.toTextureData(texname); } else if (token == "texrep") { stream >> textureRepeat[0] >> textureRepeat[1];// if (textureRepeat[0] == 0.0f && textureRepeat[1] == 0.0f)// textureData.setRepeat(false);// else// textureData.setRepeat(true); } else if (token == "texoff") { stream >> textureOffset[0] >> textureOffset[1]; } else if (token == "rot") { for (unsigned n = 0; n < 3; ++n) for (unsigned m = 0; m < 3; ++m) stream >> transform(m, n); } else if (token == "loc") { for (unsigned n = 0; n < 3; ++n) stream >> transform(3, n); } else if (token == "url") { std::string url; stream >> url; group->addDescription(url); } else if (token == "numvert") { osg::Matrix currentTransform = transform*parentTransform; unsigned num; stream >> num; if (num != 0) { vertexSet->reserve(num); for (unsigned n = 0; n < num; ++n) { osg::Vec3 p; stream >> p[0] >> p[1] >> p[2]; vertexSet->addVertex(currentTransform.preMult(p)); } } } else if (token == "numsurf") { unsigned num; stream >> num; if (0 < num) { // list of materials required- generate one geode per material std::vector<Bins> primitiveBins(fileData.getNumMaterials()); vertexSet->setCreaseAngle(creaseAngle); for (unsigned n = 0; n < num; ++n) { std::string token; stream >> token; if (token != "SURF") { osg::notify(osg::FATAL) << "osgDB ac3d reader: expected SURF line while reading object \"" << group->getName() << "\"!" << std::endl; return group.release(); } stream >> token; unsigned flags = strtol(token.c_str(), NULL, 0); stream >> token; if (token != "mat") { osg::notify(osg::FATAL) << "osgDB ac3d reader: expected mat line while reading object \"" << group->getName() << "\"!" << std::endl; return group.release(); } // read the material index unsigned matIdx; stream >> matIdx; if (primitiveBins.size() <= matIdx) { osg::notify(osg::FATAL) << "osgDB ac3d reader: invalid material number while reading object \"" << group->getName() << "\"" << std::endl; return group.release(); } // now get the correct PrimitiveBin PrimitiveBin* primitiveBin = 0; primitiveBin = primitiveBins[matIdx].getOrCreatePrimitiveBin(flags, vertexSet.get()); if (!primitiveBin) { osg::notify(osg::FATAL) << "osgDB ac3d reader: unexpected primitive flags while reading object \"" << group->getName() << "\"" << std::endl; return group.release(); } // read the refs stream >> token; if (token != "refs") { osg::notify(osg::FATAL) << "osgDB ac3d reader: expected refs line while reading object \"" << group->getName() << "\"" << std::endl; return group.release(); } unsigned nRefs = 0; stream >> nRefs; if (!stream) { osg::notify(osg::FATAL) << "osgDB ac3d reader: could not read number of refs while reading object \"" << group->getName() << "\"" << std::endl; return group.release(); } // in case this is an invalid refs count for this primitive // read further, but do not store that primitive bool acceptPrimitive = primitiveBin->beginPrimitive(nRefs); for (unsigned i = 0; i < nRefs; ++i) { // Read the vertex index unsigned index; stream >> index; if (vertexSet->size() <= index) { osg::notify(osg::FATAL) << "osgDB ac3d reader: invalid ref vertex index while reading object \"" << group->getName() << "\"" << std::endl; return group.release(); } // Read the texture corrdinates osg::Vec2 texCoord; stream >> texCoord[0] >> texCoord[1]; if (!stream) { osg::notify(osg::WARN) << "osgDB ac3d reader: could not parse texture coords while reading object \"" << group->getName() << "\" setting to (0,0)" << std::endl; stream.clear(); std::string dummy; std::getline(stream, dummy); } if (acceptPrimitive) { texCoord[0] = textureOffset[0] + texCoord[0]*textureRepeat[0]; texCoord[1] = textureOffset[1] + texCoord[1]*textureRepeat[1]; if (!primitiveBin->vertex(index, texCoord)) { return group.release(); } } } if (acceptPrimitive) { if (!primitiveBin->endPrimitive()) { return group.release(); } } } for (unsigned i = 0; i < primitiveBins.size(); ++i) primitiveBins[i].finalize(group.get(), fileData.getMaterial(i), textureData); } } else if (token == "kids") { unsigned num; stream >> num; if (num != 0) { for (unsigned n = 0; n < num; n++) { osg::Node *k = readObject(stream, fileData, transform*parentTransform, textureData); if (k == 0) { osg::notify(osg::FATAL) << "osgDB ac3d reader: error reading child object" << std::endl; return group.release(); } else { osg::LightSource *ls = dynamic_cast<osg::LightSource*>(k); if (ls) { osg::StateSet* lightStateSet = group->getOrCreateStateSet(); group->setStateSet(lightStateSet); group->setCullingActive(false); ls->setStateSetModes(*lightStateSet, osg::StateAttribute::ON); } group->addChild(k); } } } else if (objectType == ObjectTypeLight) { // add a light source to the scene 1 Nov 2003 osg::Light* ac3dLight = fileData.getNextLight(); osg::Matrix tt = transform*parentTransform; ac3dLight->setPosition(osg::Vec4(tt(3, 0), tt(3, 1), tt(3, 2), 1)); ac3dLight->setDirection(osg::Matrix::transform3x3(osg::Vec3(0.0f, 0.0f, -1.0f), tt)); ac3dLight->setAmbient(osg::Vec4(0.5f,0.5f,0.5f,1.0f)); ac3dLight->setDiffuse(osg::Vec4(0.5f,0.5f,0.5f,1.0f)); ac3dLight->setSpecular(osg::Vec4(1.0f,1.0f,0.5f,1.0f)); osg::LightSource* ac3dLightSource = new osg::LightSource; ac3dLightSource->setDataVariance(osg::Object::STATIC); ac3dLightSource->setLight(ac3dLight); ac3dLightSource->setLocalStateSetModes(osg::StateAttribute::ON); // for some mad reason, you need to set this so that the light works. WHY? return ac3dLightSource; } return group.release(); } } return group.release();}osg::Node*readFile(std::istream& stream, const osgDB::ReaderWriter::Options* options){ FileData fileData(options); osg::Matrix identityTransform; osg::Node* node = readObject(stream, fileData, identityTransform, TextureData()); if (node) node->setName("World"); return node;}} // namespace ac3d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -