bool DemoApp::LoadContent(){ ObjParser reader; reader.Read(GetFullPath("assets/cube.obj").c_str(), &_scene); _scene.renderType = Scene::RENDER_TYPE_FRAME; _scene.camera = &_camera; _scene.lightList[0] = new Light(); _scene.lightList[0]->type = Light::TYPE_DIRECTION; _scene.lightList[0]->ambientColor = Color{ 0.0f, 0.0f, 0.0f, 0.3f }; _scene.lightList[0]->diffuseColor = Color{ 1.0f, 0.0f, 0.0f, 1.0f }; _scene.lightList[0]->specularColor = Color{ 1.0f, 1.0f, 1.0f, 1.0f }; _scene.lightList[0]->pos = Vector3D(0.0f, 0.0f, 0.0f); _scene.lightList[0]->dir = Vector3D(1.0f, -1.0f, 1.0f); _scene.lightList[1] = new Light(); _scene.lightList[1]->type = Light::TYPE_POINT; _scene.lightList[1]->ambientColor = Color{ 0.0f, 0.0f, 0.0f, 1.0f }; _scene.lightList[1]->diffuseColor = Color{ 1.0f, 0.0f, 1.0f, 1.0f }; _scene.lightList[1]->specularColor = Color{ 0.0f, 0.0f, 0.0f, 1.0f }; _scene.lightList[1]->pos = Vector3D(2.0f, 0.0f, 0.0f); _scene.lightList[1]->range = 200.0f; _scene.lightList[1]->kc = 0.0f; _scene.lightList[1]->kl = 1.0f; _scene.lightList[1]->kq = 0.0f; _scene.lightNum = 2; /*准备顶点缓冲数据*/ _currMesh = _scene.GetMesh(0); PreSetVSConstBufferSize(_currMesh, sizeof(MVPConstBuffer)); PreSetPSConstBufferSize(_currMesh, sizeof(PhongConstBuffer)); InitVisual(_currMesh, L"shader/Phong.fx", "assets/t_02.dds"); return true; }
void loadObj( const std::string& filename ) { ObjParser parser; if (! parser.parseFile( filename ) ) { std::cerr << "Failed to load .obj file: " << parser.errorText() << std::endl << "FILE: " << parser.filename() << ":" << parser.lineNumber() << std::endl << "LINE: " << parser.lineText() << std::endl; } else { std::cout << parser.dump(); } }
ObjTriangleMesh::ObjTriangleMesh( const Transform *o2c, const Transform *c2o, int subdlevels, const std::string &objfile ): Shape(o2c, c2o) { std::vector<Point> points; std::vector<Vector> normals; std::vector<uv> uvs; std::vector<int> vIndex; std::vector<int> nIndex; std::vector<int> uvIndex; ObjParser parser = ObjParser(objfile, &points, &normals, &uvs, &vIndex, &nIndex, &uvIndex); bool success = parser.parseFile(); assert(success); size_t numTriangles = vIndex.size() / 3; size_t numVertices = vIndex.size(); LOG_INFO("Found " << numTriangles << " triangles and " << numVertices << " vertices."); Point *P = new Point[ numVertices ]; Vector *N = new Vector[ numVertices ]; assert(nIndex.size() == vIndex.size()); uv *UV = NULL; if(uvs.size()){ assert(uvIndex.size() == vIndex.size()); UV = new uv[ numVertices ]; } int *vertexIndex = new int[3 * numTriangles]; for (size_t i=0; i < 3*numTriangles; i++) { // obj files starts vert indices at 1 instead of 0. vertexIndex[i] = vIndex[i] - 1; nIndex[i]--; if(UV) uvIndex[i]--; assert(vertexIndex[i] < numVertices); } for (size_t i = 0; i < numVertices; i++) { P[i] = points[vertexIndex[i]]; N[i] = normals[nIndex[i]]; if (N[i].x == 0. && N[i].y == 0. && N[i].z == 0.) { LOG_WARNING("Found empty normal. Setting to 0,1,0"); N[i] = Vector(0,1,0); } if (UV){ UV[i] = uvs[uvIndex[i]]; } vertexIndex[i] = (int)i; } if (subdlevels){ m_shape = shared_ptr<Shape>(new LoopSubdivMesh(o2c, c2o, (int)numTriangles, (int)numVertices, vertexIndex, P, UV, subdlevels)); } else { m_shape = shared_ptr<Shape>(new TriangleMesh(o2c, c2o, (int)numTriangles, (int)numVertices, vertexIndex, P, N, UV)); } delete[] vertexIndex; delete[] P; delete[] N; if(UV) delete[] UV; }
Model *ModelBuilder::buildModel(const char* Filename) { ObjModel *objModel; ObjParser objParser; std::cout << "Filename " << Filename << std::endl; objModel = objParser.loadModelFromFile(Filename); // assemble vertices and materials from collected data unsigned int numberOfFaces = (int)objModel->faces.size(); unsigned int numberOfVertices = numberOfFaces * 3; std::vector<Vertex> vertices(numberOfVertices); std::vector<unsigned int> indices(numberOfVertices); FaceGroup currentFaceGroup; for(int i = 0; i < numberOfFaces; i++) { // @todo: check for different mats and create face groups unsigned int PosIdx0 = objModel->faces[i].pidx[0] - 1; unsigned int PosIdx1 = objModel->faces[i].pidx[1] - 1; unsigned int PosIdx2 = objModel->faces[i].pidx[2] - 1; unsigned int TexIdx0 = objModel->faces[i].tidx[0] - 1; unsigned int TexIdx1 = objModel->faces[i].tidx[1] - 1; unsigned int TexIdx2 = objModel->faces[i].tidx[2] - 1; // Positionen der Vertices setzen Vector a = vertices[i * 3].position = objModel->positions[PosIdx0]; Vector b = vertices[i * 3 + 1].position = objModel->positions[PosIdx1]; Vector c = vertices[i * 3 + 2].position = objModel->positions[PosIdx2]; // Wenn aktuelles Objekt Textkoordinaten enthaelt, eben diese setzen vertices[i * 3].texCoordS = objModel->textureCoordinates[TexIdx0].s; vertices[i * 3 + 1].texCoordS = objModel->textureCoordinates[TexIdx1].s; vertices[i * 3 + 2].texCoordS = objModel->textureCoordinates[TexIdx2].s; vertices[i * 3].texCoordT = objModel->textureCoordinates[TexIdx0].t; vertices[i * 3 + 1].texCoordT = objModel->textureCoordinates[TexIdx1].t; vertices[i * 3 + 2].texCoordT = objModel->textureCoordinates[TexIdx2].t; // Normalen berechnen Vector normal = (b - a).cross(c - a); normal.normalize(); vertices[i * 3].normal = vertices[i * 3 + 1].normal = vertices[i * 3 + 2].normal = normal; indices[i * 3] = i * 3; indices[i * 3 + 1] = i * 3 + 1; indices[i * 3 + 2] = i * 3 + 2; } for (unsigned int i = 0; i < numberOfVertices; i++) { vertices[i].normal.normalize(); } Model *newModel = new Model(); newModel->setMaterials(objModel->materials, objModel->materialCount); newModel->setVertices(vertices); newModel->uploadVerticesToBuffer<Vertex>((unsigned int)vertices.size(), &vertices[0]); newModel->uploadIndicesToBuffer<unsigned int>((unsigned int)indices.size(), &indices[0]); return newModel; }
bool Scene::loadScene(std::string sceneName) { //Get scene file path std::string file = PathReader::getPath("", sceneName.c_str(), "xml"); //Load scene file. tinyxml2::XMLDocument doc; doc.LoadFile(file.c_str()); //Invalid xml. if(doc.ErrorID() != XML_NO_ERROR) { cubeMappingSkybox = nullptr; light = nullptr; errorDescription = "Scene file doesn't exists."; return true; } //Variable used to flag the scene as erroneous. bool errorsInScene = false; //Get scene type. //Assume spectral as default. std::string sceneType = doc.RootElement()->Attribute("type"); sceneType = sceneType == "" ? "Spectral" : sceneType; //Read camera. XMLElement* cameraElement = doc.RootElement()->FirstChildElement("camera"); errorsInScene = errorsInScene || setupCamera(cameraElement); //Light. const XMLElement* lightElement = doc.RootElement()->FirstChildElement("light"); const XMLElement* lightOrigin = lightElement->FirstChildElement("origin"); if(lightElement) { std::string lightType = lightElement->Attribute("type"); if(sceneType == "RGB") { bool rgbLightCreation = setupRGBLight(lightElement, lightOrigin, lightType); errorsInScene = errorsInScene || rgbLightCreation; } else { bool spectralLightCreation = setupSpectralLight(lightElement, lightOrigin, lightType); errorsInScene = errorsInScene || spectralLightCreation; } } else { errorDescription = errorDescription + "The scene doesn't contain any light.\n"; errorsInScene = true; } //Eventually set a cube mapping skybox. setupSkyboxWithCubeMapping(doc); //Objects XMLElement *objectsElement = doc.RootElement()->FirstChildElement("objects"); if(!objectsElement) { errorDescription = errorDescription + "The scene doesn't contain any object.\n"; errorsInScene = true; } //Init geometric objects. for(XMLElement *objectElement = objectsElement->FirstChildElement("object"); objectElement != NULL; objectElement = objectElement->NextSiblingElement("object")) { std::string type = objectElement->Attribute("type"); //Object creation Model* object; bool objectCreation = setupObject(&object, objectElement); errorsInScene = errorsInScene || objectCreation; //Object material creation. const XMLElement* material = objectElement->FirstChildElement("material"); if(sceneType == "RGB") { bool materialRGBCreation = setupRGBObjectMaterial(object, material); errorsInScene = errorsInScene || materialRGBCreation; } else { bool materialBRDFCreation = setupBRDFObjectMaterial(object, material); errorsInScene = errorsInScene || materialBRDFCreation; } //add object. objects.push_back(object); } //Init polygonal mesh. for(XMLElement *objectElement = objectsElement->FirstChildElement("mesh"); objectElement != NULL; objectElement = objectElement->NextSiblingElement("mesh")) { const XMLElement* objFile = objectElement->FirstChildElement("objFile"); bool backFaceCulling = false; if(attributesExist(objFile, {"backFaceCulling"})) { backFaceCulling = objFile->FindAttribute("backFaceCulling")->BoolValue(); } std::string objName = objFile->Attribute("name"); std::string objFilePath = PathReader::getPath("OBJs", objName.c_str(), "obj"); ObjParser objParser; objParser.parseObj(objFilePath.c_str(), backFaceCulling); std::vector<Model *> pList = objParser.getPolygonalShapes(); const XMLElement* material = objectElement->FirstChildElement("material"); for(std::vector<Model *>::size_type i = 0; i != pList.size(); i++) { if(sceneType == "RGB") { bool materialRGBCreation = setupRGBObjectMaterial(pList[i], material); errorsInScene = errorsInScene || materialRGBCreation; } else { bool materialBRDFCreation = setupBRDFObjectMaterial(pList[i], material); errorsInScene = errorsInScene || materialBRDFCreation; } } //Setup AABB. const XMLElement* aabbElement = objectElement->FirstChildElement("aabb"); AxisAlignedBoundingBox aabb; setupAABB(aabb, aabbElement); //Create mesh. Model* mesh = new PolygonalMesh(pList, aabb); //Add mesh. objects.push_back(mesh); } //SCLT specific configuration. errorsInScene = errorsInScene || setupSCLTParameter(doc, sceneType); return errorsInScene; }