Пример #1
0
bool BulletContent::Initialize(std::string& err)
{
    typedef VertexPosUV BulletVertex;
    RenderIOAttributes vertIns = BulletVertex::GetVertexAttributes();


    #pragma region Meshes

    for (unsigned int i = 0; i < B_NUMBER_OF_BULLETS; ++i)
    {
        bulletMesh.SubMeshes.push_back(MeshData(false, PT_TRIANGLE_LIST));
    }

    std::vector<BulletVertex> vertices;
    std::vector<unsigned int> indices;

    Assimp::Importer importer;
    unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality;

    for (unsigned int i = 0; i < B_NUMBER_OF_BULLETS; ++i)
    {
        //Get the file for this bullet type.
        std::string file = "Content/Game/Meshes/Bullets/";
        switch ((Bullets)i)
        {
            case B_PUNCHER:
                file += "Puncher.obj";
                break;
            case B_TERRIBLE_SHOTGUN:
                file += "Terrible Shotgun.obj";
                break;
            case B_SPRAY_N_PRAY:
                file += "Spray and Pray.obj";
                break;
            case B_CLUSTER:
                file += "Cluster.obj";
                break;

            default:
                assert(false);
        }

        const aiScene* scene = importer.ReadFile(file, flags);

        //Make sure the scene is valid.
        if (scene == 0)
        {
            err = "Error loading '" + file + "': " + importer.GetErrorString();
            return false;
        }
        if (scene->mNumMeshes != 1)
        {
            err = "Mesh '" + file + "' has " + std::to_string(scene->mNumMeshes) + " meshes in it";
            return false;
        }

        aiMesh* mesh = scene->mMeshes[0];

        //Make sure the mesh is valid.
        assert(mesh->HasFaces());
        if (!mesh->HasPositions() || !mesh->HasTextureCoords(0))
        {
            err = "Mesh '" + file + "' is missing positions or UVs!";
            return false;
        }

        //Populate the vertex/index buffer data.
        vertices.resize(mesh->mNumVertices);
        for (unsigned int j = 0; j < mesh->mNumVertices; ++j)
        {
            vertices[j].Pos = *(Vector3f*)(&mesh->mVertices[j].x);
            vertices[j].UV = *(Vector2f*)(&mesh->mTextureCoords[0][j].x);
        }
        indices.resize(mesh->mNumFaces * 3);
        for (unsigned int j = 0; j < mesh->mNumFaces; ++j)
        {
            aiFace& fce = mesh->mFaces[j];
            if (fce.mNumIndices != 3)
            {
                err = "A face in mesh '" + file + "' has a non-tri face with " +
                      std::to_string(fce.mNumIndices) + " indices!";
                return false;
            }

            indices[(j * 3)] = fce.mIndices[0];
            indices[(j * 3) + 1] = fce.mIndices[1];
            indices[(j * 3) + 2] = fce.mIndices[2];
        }

        //Create the vertex/index buffers.
        bulletMesh.SubMeshes[i].SetVertexData(vertices, MeshData::BUF_STATIC, vertIns);
        bulletMesh.SubMeshes[i].SetIndexData(indices, MeshData::BUF_STATIC);
    }

    #pragma endregion

    #pragma region Textures

    {
        Array2D<Vector4b> values(1, 1, Vector4b((unsigned char)255, 255, 255, 255));
        defaultTex.Create();
        defaultTex.SetColorData(values);
    }

    #pragma endregion

    #pragma region Materials

    {
        SerializedMaterial serMat;
        serMat.VertexInputs = vertIns;

        DataLine vIn_Pos(VertexInputNode::GetInstance(), 0),
                 vIn_UV(VertexInputNode::GetInstance(), 1);
        
        DataNode::Ptr screenPos = SpaceConverterNode::ObjPosToScreenPos(vIn_Pos, "screenPos");
        serMat.MaterialOuts.VertexPosOutput = DataLine(screenPos, 1);

        serMat.MaterialOuts.VertexOutputs.push_back(ShaderOutput("fIn_UV", vIn_UV));

        DataLine fIn_UV(FragmentInputNode::GetInstance(), 0);

        DataNode::Ptr tex(new TextureSample2DNode(fIn_UV, UNIFORM_TEXTURE, "texSample"));
        DataLine texRGB(tex, TextureSample2DNode::GetOutputIndex(CO_AllColorChannels));

        DataNode::Ptr colorParam(new ParamNode(3, UNIFORM_COLOR));

        DataNode::Ptr finalRGB(new MultiplyNode(texRGB, colorParam, "finalRGB"));
        DataNode::Ptr finalColor(new CombineVectorNode(finalRGB, 1.0f, "finalColor"));

        serMat.MaterialOuts.FragmentOutputs.push_back(ShaderOutput("fOut_Color", finalColor));

        auto genMat = ShaderGenerator::GenerateMaterial(serMat, bulletParams, BlendMode::GetOpaque());
        if (!genMat.ErrorMessage.empty())
        {
            err = "Error generating bullet material: " + genMat.ErrorMessage;
            return false;
        }
        bulletMat = genMat.Mat;
    }

    #pragma endregion

    return true;
}
	void GLAssimpMeshBinding::load(const aiScene *scene, const aiMesh *mesh) {
		// only process if we haven't already loaded this - otherwise is just GL reload
		if (!this->mesh) {
			Property *prop = btGetContext()->appProperties->get("debug_assimp");
			if (prop) {
				debugAssimp = prop->getBoolValue();
			}
			this->mesh = mesh;
			hasBones = (mesh->mNumBones > 0);
			if (hasBones) {
				vertSkinnedAtts = new GLAssimpSkinnedMeshVertex[mesh->mNumVertices];
			} else {
				vertBasicAtts = new GLAssimpMeshVertex[mesh->mNumVertices];
			}
			if (hasBones) {
				for (U32 i = 0; i < mesh->mNumVertices; i++) {
					aiVector3D vert = mesh->mVertices[i];
					aiVector3D normal = mesh->mNormals[i];
					aiVector3D uv = mesh->mTextureCoords[0][i];
					vertSkinnedAtts[i].position = Vector3f(vert.x, vert.y, vert.z);
					vertSkinnedAtts[i].normal = Vector3f(normal.x, normal.y, normal.z);
					vertSkinnedAtts[i].uv = Vector2f(uv.x, uv.y);
					vertSkinnedAtts[i].bones = Vector4b(0, 0, 0, 0);
					vertSkinnedAtts[i].weights = Vector4f(0, 0, 0, 0);
				}
				U32 *weightCounts = new U32[mesh->mNumVertices];
				memset(weightCounts, 0, mesh->mNumVertices * 4);
				BOOL32 discardedWeights = FALSE;
				for (U8 i = 0; i < (U8)mesh->mNumBones; i++) {
					aiBone *bone = mesh->mBones[i];
					for (U32 j = 0; j < bone->mNumWeights; j++) {
						U32 vertIdx = bone->mWeights[j].mVertexId;
						F32 weight = bone->mWeights[j].mWeight;
						U32 weightNum = weightCounts[vertIdx];
						if (weightNum < 4) {
							vertSkinnedAtts[vertIdx].bones[weightNum] = i;
							vertSkinnedAtts[vertIdx].weights[weightNum] = weight;
							weightCounts[vertIdx]++;
						} else {
							discardedWeights = TRUE;
						}
					}
				}
				delete [] weightCounts;
				if (discardedWeights) {
					logmsg("AssimpBind Warning: Too many bone weights - discarding!");
				}
			} else {
				for (U32 i = 0; i < mesh->mNumVertices; i++) {
					aiVector3D vert = mesh->mVertices[i];
					aiVector3D normal = mesh->mNormals[i];
					aiVector3D uv = mesh->mTextureCoords[0][i];
					vertBasicAtts[i].position = Vector3f(vert.x, vert.y, vert.z);
					vertBasicAtts[i].normal = Vector3f(normal.x, normal.y, normal.z);
					vertBasicAtts[i].uv = Vector2f(uv.x, uv.y);
				}
			}
			loadMaterials(scene->mMaterials[mesh->mMaterialIndex]);
		}
		U16 *faceIndices = new U16[this->mesh->mNumFaces * 3];
		for (U32 i = 0; i < this->mesh->mNumFaces; i++) {
			aiFace face = this->mesh->mFaces[i];
			faceIndices[i*3] = face.mIndices[0];
			faceIndices[i*3+1] = face.mIndices[1];
			faceIndices[i*3+2] = face.mIndices[2];
		}
		loadGeometry(this->mesh, faceIndices);
		delete [] faceIndices;
	}