Exemple #1
0
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;
}
Exemple #2
0
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;
}