예제 #1
0
ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlending textureBlending, unsigned int particleCountMax)
{
    Texture* texture = NULL;
    texture = Texture::create(textureFile, false);

    if (!texture)
    {
        GP_ERROR("Failed to create texture for particle emitter.");
        return NULL;
    }
    GP_ASSERT(texture->getWidth());
    GP_ASSERT(texture->getHeight());

    // Use default SpriteBatch material.
    SpriteBatch* batch =  SpriteBatch::create(texture, NULL, particleCountMax);
    texture->release(); // batch owns the texture.
    GP_ASSERT(batch);

    ParticleEmitter* emitter = new ParticleEmitter(batch, particleCountMax);
    GP_ASSERT(emitter);

    // By default assume only one frame which uses the entire texture.
    emitter->setTextureBlending(textureBlending);
    emitter->_spriteTextureWidth = texture->getWidth();
    emitter->_spriteTextureHeight = texture->getHeight();
    emitter->_spriteTextureWidthRatio = 1.0f / (float)texture->getWidth();
    emitter->_spriteTextureHeightRatio = 1.0f / (float)texture->getHeight();

    Rectangle texCoord((float)texture->getWidth(), (float)texture->getHeight());
    emitter->setSpriteFrameCoords(1, &texCoord);

    return emitter;
}
예제 #2
0
void Cc3dMesh::initTexCoordList(const float texCoordArray[],int texCoordArrayLen){
    m_texCoordList.clear();
    for(int i=0;i<texCoordArrayLen;i+=2){
        Cc3dVector2 texCoord(texCoordArray[i],texCoordArray[i+1]);
        m_texCoordList.push_back(texCoord);
    }
}
예제 #3
0
void Triangle2::convertBarycentricToUVs(float &u, float &v)
{
    // TODO: Make it work for polygon (tri/quad).
    
    Vector3D t0 = texCoord(0)->data().position;
    Vector3D t1 = texCoord(1)->data().position;
    Vector3D t2 = texCoord(2)->data().position;
    
    Vector3D e1 = t1 - t0;
    Vector3D e2 = t2 - t0;
   
    Vector3D final = t0 + e1 * u + e2 * v;
    
    u = final.x;
    v = final.y;
}
예제 #4
0
void EarthWidget::buildModel()
{
    // load texture
    QImage im(":/images/earthmap.jpg");
    Q_ASSERT(!im.isNull());
    _textureId = bindTexture(im);

    // build sphere data
    _vertexPositions.reserve(M * N);
    _normals.reserve(M * N);
    _texCoords.reserve(M * N);
    _vertIds = QVector<QVector<int>>(M, QVector<int>(N));
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            float xratio = 1.0f / (N - 1) * j;
            float yratio = 1.0f / (M - 1) * i;
            float xangle = M_PI * 2 * xratio;
            float yangle = M_PI * yratio - M_PI_2;
            QVector4D pos(cos(xangle)*cos(yangle), sin(yangle), sin(xangle)*cos(yangle),  1);
            _vertexPositions << pos;
            QVector3D normal(cos(xangle)*cos(yangle), sin(yangle), sin(xangle)*cos(yangle));
            _normals << normal;
            QVector2D texCoord(1.0 - xratio, yratio);
            _texCoords << texCoord;
            _vertIds[i][j] = _texCoords.size() - 1;
        }
    }
}
예제 #5
0
std::shared_ptr<SimpleMesh> SimpleMeshCreator::sphere(float radius, unsigned int numLoops,
                                                      unsigned int segmentsPerLoop, vec4 color) {
    auto spheremesh = std::make_shared<SimpleMesh>();

    numLoops = std::max(4u, numLoops);
    segmentsPerLoop = std::max(8u, segmentsPerLoop);

    // Set identity matrix
    spheremesh->setModelMatrix(mat4(1.f));

    // Create Vertices
    auto normals = std::make_shared<Vec3BufferRAM>((numLoops + 1) * (segmentsPerLoop + 1));
    auto normalBuffer = std::make_shared<Buffer<vec3>>(normals);

    unsigned int pointsPerLine = segmentsPerLoop + 1;
    for (unsigned int i = 0; i <= numLoops; ++i) {
        for (unsigned int j = 0; j <= segmentsPerLoop; ++j) {
            float theta =
                (i * static_cast<float>(M_PI) /
                 numLoops);  // + ((static_cast<float>(M_PI) * j) / (segmentsPerLoop * numLoops));

            if (i == numLoops) theta = static_cast<float>(M_PI);

            float phi = j * 2 * static_cast<float>(M_PI) / segmentsPerLoop;
            float sinTheta = std::sin(theta);
            float sinPhi = std::sin(phi);
            float cosTheta = std::cos(theta);
            float cosPhi = std::cos(phi);
            vec3 normal(cosPhi * sinTheta, sinPhi * sinTheta, cosTheta);
            vec3 vert(normal * radius);
            vec3 texCoord(static_cast<float>(j) / segmentsPerLoop, static_cast<float>(i) / numLoops,
                          0.0f);
            spheremesh->addVertex(vert, texCoord, color);
            normals->set(i * pointsPerLine + j, normal);
        }
    }
    spheremesh->addBuffer(BufferType::NormalAttrib, normalBuffer);

    // Create Indices
    // compute indices
    spheremesh->setIndicesInfo(DrawType::Triangles, ConnectivityType::None);
    for (unsigned int y = 0; y < numLoops; ++y) {
        auto indices = std::make_shared<IndexBufferRAM>(pointsPerLine * 2);
        auto indexBuf = std::make_shared<IndexBuffer>(indices);

        unsigned int offset = y * pointsPerLine;
        std::size_t count = 0;
        for (unsigned int x = 0; x < pointsPerLine; ++x) {
            indices->set(count++, offset + x);
            indices->set(count++, offset + x + pointsPerLine);
        }

        spheremesh->addIndicies(Mesh::MeshInfo(DrawType::Triangles, ConnectivityType::Strip),
                                indexBuf);
    }

    return spheremesh;
}
예제 #6
0
void Triangle2::computeNormalsIfNeeded()
{
    // TODO: Make it work for polygon (tri/quad).
    if (normalsAreValid)
        return;
    
    Vector3D u, v;
    
    u = texCoord(0)->data().position - texCoord(1)->data().position;
    v = texCoord(1)->data().position - texCoord(2)->data().position;
    texCoordNormal = u.Cross(v);    
    
    u = vertex(0)->data().position - vertex(1)->data().position;
    v = vertex(1)->data().position - vertex(2)->data().position;
    vertexNormal = u.Cross(v);
    
    normalsAreValid = true;
}
예제 #7
0
TexCoordNode *Triangle2::texCoordNotInEdge(const TexCoordEdge *edge) const
{
    for (unsigned int i = 0; i < count(); i++)
    {
        TexCoordNode *currentTexCoord = texCoord(i);
        if (currentTexCoord != edge->texCoord(0) &&
            currentTexCoord != edge->texCoord(1))
            return currentTexCoord;
    }
    return NULL;
}
예제 #8
0
void GeometryCreator::fillGridData(std::vector<Vertex_PositionTexCoord>& vertices, unsigned int rowCount, unsigned int columnCount)
{
    for (unsigned int rowIndex = 0; rowIndex < rowCount; rowIndex++)
    {
        for (unsigned int columnIndex = 0; columnIndex < columnCount; columnIndex++) 
        {
            // Normalize the row position to get it in a 0 to 1 range
            glm::vec2 texCoord(rowIndex / static_cast<float>(rowCount), columnIndex / static_cast<float>(columnCount));

            int index = rowIndex * columnCount + columnIndex;
            vertices[index].texCoord = texCoord;
        }
    }
}
void CText2D::Render(float _posX, float _posY)
{
	__INT32 posX = __INT32 (_posX);
	__INT32 posY = __INT32 (_posY);
	for(int i = 0; i < strlen(m_strText); i++) 
	{
		SCharMap* map = m_CharMap->GetMap(m_strText[i]);
		if(map != NULL)
		{
			SRect<__INT32> border(posX, posY, 30, 30);
			SRect<__INT32> texCoord(map->x, map->y, map->w, map->h);
			g->DrawImageRegion(border, texCoord, m_img);
			posX += 30;
		}
	}
}
void GLES20RenderEngine::endGroup() {

    const Group group(mGroupStack.top());
    mGroupStack.pop();

    // activate the previous render target
    GLuint fbo = 0;
    if (!mGroupStack.isEmpty()) {
        fbo = mGroupStack.top().fbo;
    }
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    // set our state
    Texture texture(Texture::TEXTURE_2D, group.texture);
    texture.setDimensions(group.width, group.height);
    glBindTexture(GL_TEXTURE_2D, group.texture);

    mState.setPlaneAlpha(1.0f);
    mState.setPremultipliedAlpha(true);
    mState.setOpaque(false);
    mState.setTexture(texture);
    mState.setColorMatrix(group.colorTransform);
    glDisable(GL_BLEND);

    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
    Mesh::VertexArray<vec2> texCoord(mesh.getTexCoordArray<vec2>());
    position[0] = vec2(0, 0);
    position[1] = vec2(group.width, 0);
    position[2] = vec2(group.width, group.height);
    position[3] = vec2(0, group.height);
    texCoord[0] = vec2(0, 0);
    texCoord[1] = vec2(1, 0);
    texCoord[2] = vec2(1, 1);
    texCoord[3] = vec2(0, 1);
    drawMesh(mesh);

    // reset color matrix
    mState.setColorMatrix(mat4());

    // free our fbo and texture
    glDeleteFramebuffers(1, &group.fbo);
    glDeleteTextures(1, &group.texture);
}
void RPG_GuiMinimap_VisionGUI::OnPaint(VGraphicsInfo &Graphics, const VItemRenderInfo &parentState)
{ 
  VASSERT(m_maskShader);
  VImageState &img = m_Image.m_States[GetCurrentState()];
  VColorRef iColor = parentState.iFadeColor;
  VRectanglef rect = GetBoundingBox();
  VRectanglef texCoord(0.f, 0.f, 1.f, 1.f);
  VTextureObject *pTex = img.GetCurrentTexture();

  // Update shader registers in the const tables of the shader pass:
  m_regTransform.SetRegisterValueF(m_maskShader, m_transform.data);
  m_regFadeColor.SetRegisterValueF(m_maskShader, m_fadeColor.data);

  // Render the quad with our mask shader
  Overlay2DVertex_t v[6];
  IVRender2DInterface::CreateQuadVertices(rect.m_vMin.x,rect.m_vMin.y,rect.m_vMax.x,rect.m_vMax.y,texCoord.m_vMin.x,texCoord.m_vMin.y,texCoord.m_vMax.x,texCoord.m_vMax.y,iColor,v);
  VSimpleRenderState_t state = VGUIManager::DefaultGUIRenderState();
  Graphics.Renderer.Draw2DBufferWithShader(6, v, pTex, *m_maskShader);
}
예제 #12
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
cvf::Vec2f RivTernaryScalarMapper::mapToTextureCoord(double soil, double sgas, bool isTransparent) const
{
    // Clamp the float texture coordinate to avoid edge issues when looking up the texture coordinate 
    // The issue was detected on Linux, no similar issues has been seen on Windows
    double edgeClampDelta = 0.001;

    double soilNormalized = (soil - m_rangeMinSoil) * m_soilFactor;
    soilNormalized = cvf::Math::clamp(soilNormalized, edgeClampDelta, 1.0 - edgeClampDelta);

    double sgasNormalized = (sgas - m_rangeMinSgas) * m_sgasFactor;
    sgasNormalized = cvf::Math::clamp(sgasNormalized, edgeClampDelta, 1.0 - soilNormalized);
    sgasNormalized /= 2.0;

    if (isTransparent)
    {
        sgasNormalized += 0.5;
    }

    cvf::Vec2f texCoord(static_cast<float>(soilNormalized), static_cast<float>(sgasNormalized));
    return texCoord;
}
예제 #13
0
    //
    // Creates a cylinder at the origin oriented along the Z-axis. 'radius'
    // represents the distance from the center to the inner ring. 'height'
    // represents the amount to extrude along the Z-axis.  'numStacks' is the
    // number of layers along the Z-axis, 'numSlices' is the number of radial
    // divisions.
    //
    STShape* CreateCylinder(
        float radius, float height,
        unsigned int numSlices, unsigned int numStacks)
    {
        STShape* result = new STShape();

        for(unsigned int ii = 0; ii <= numStacks; ++ii) {
            for(unsigned int jj = 0; jj < numSlices; ++jj) {
                const float theta =
                    float(jj) * 2.0f * float(M_PI) / float(numSlices);
                STPoint3 position(radius * cosf(theta),
                                  radius * sinf(theta),
                                  height * (float(ii) / numStacks));
                STPoint2 texCoord(ii / float(numStacks),
                                  jj / float(numSlices - 1));

                result->AddVertex(
                    STShape::Vertex(position, STVector3::Zero, texCoord));
            }
        }

        for(unsigned int ii = 0; ii < numStacks; ii++) {
            for(unsigned int jj = 0; jj < numSlices; jj++) {
                int jjPlus1 = (jj + 1) % numSlices;
                result->AddFace(STShape::Face(
                    (ii + 1)*numSlices + jj,
                    (ii + 0)*numSlices + jj,
                    (ii + 0)*numSlices + jjPlus1));
                result->AddFace(STShape::Face(
                    (ii + 1)*numSlices + jj,
                    (ii + 0)*numSlices + jjPlus1,
                    (ii + 1)*numSlices + jjPlus1));
            }
        }

        result->GenerateNormals();
        return result;
    }
예제 #14
0
void ParticleEmitter::setTexture(Texture* texture, BlendMode blendMode)
{
    // Create new batch before releasing old one, in case the same texture
    // is used for both (so it's not released before passing to the new batch).
    SpriteBatch* batch =  SpriteBatch::create(texture, NULL, _particleCountMax);
    batch->getSampler()->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);

    // Free existing batch
    SAFE_DELETE(_spriteBatch);

    _spriteBatch = batch;
    _spriteBatch->getStateBlock()->setDepthWrite(false);
    _spriteBatch->getStateBlock()->setDepthTest(true);

    setBlendMode(blendMode);
    _spriteTextureWidth = texture->getWidth();
    _spriteTextureHeight = texture->getHeight();
    _spriteTextureWidthRatio = 1.0f / (float)texture->getWidth();
    _spriteTextureHeightRatio = 1.0f / (float)texture->getHeight();

    // By default assume only one frame which uses the entire texture.
    Rectangle texCoord((float)texture->getWidth(), (float)texture->getHeight());
    setSpriteFrameCoords(1, &texCoord);
}
예제 #15
0
void Cball::makeBall(float r,int nSlice,int nStack,string texFilePath){
	
	//make ball
	float dA=360.0/nSlice;
    float dB=180.0/nStack;
    const float PIDIV180=c3d_PI/180;
    vector<Cc3dVector4> positionList;
    vector<Cc3dVector2> texCoordList;
    vector<Cc3dVector4> normalList;
    vector<Cc3dIDTriangle> IDtriList;
    //generate positionList, texCoordList, normalList, colorList
    for(int i=0;i<=nStack;i++){
        float B=-90+i*dB;
        float y=r*sinf(B*PIDIV180);
        float cosB=cosf(B*PIDIV180);
        for (int j=0; j<=nSlice; j++) {
            float A=j*dA;
            float R=r*cosB;
            float x=R*cosf(A*PIDIV180);
            float z=R*sinf(A*PIDIV180);
            Cc3dVector4 position(x,y,z,1);
            float s=(float)j/nSlice+0.25;
            float t=1-(float)i/nStack;
            Cc3dVector2 texCoord(s,t);
            Cc3dVector4 normal=normalize(cc3dv4(position.x(), position.y(), position.z(), 0));
            positionList.push_back(position);
            texCoordList.push_back(texCoord);
            normalList.push_back(normal);
        }
    }
    //generate IDtriList
    for(int i=0;i<nStack;i++){
        for(int j=0;j<nSlice;j++){
            int vID_ld=(nSlice+1)*i+j;
            int vID_rd=vID_ld+1;
            int vID_ru=vID_rd+(nSlice+1);
            int vID_lu=vID_ru-1;
            Cc3dIDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
            Cc3dIDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
            IDtriList.push_back(IDtri0);
            IDtriList.push_back(IDtri1);
        }
    }
    Cc3dSubMesh*subMesh=new Cc3dSubMesh();
	subMesh->autorelease();
	int nPos=(int)positionList.size();
	for(int i=0;i<nPos;i++){
		Cc3dVector4&pos=positionList[i];
		Cc3dVector2&texCoord=texCoordList[i];
		Cc3dVector4&norm=normalList[i];
		subMesh->addVertex(Cc3dVertex(pos,texCoord,norm));
	}
	int nIDtri=(int)IDtriList.size();
	for(int i=0;i<nIDtri;i++){
		Cc3dIDTriangle&IDtri=IDtriList[i];
		subMesh->addIDtri(IDtri);
	}


	//--texture
	if(texFilePath.empty()==false){
		Cc3dTexture*texture=Cc3dTextureCache::sharedTextureCache()->addImage(texFilePath,GL_CLAMP_TO_EDGE,GL_CLAMP_TO_EDGE);
		subMesh->setTexture(texture);
	}

	//----mesh
	Cc3dMesh*mesh=new Cc3dMesh();
	mesh->autorelease();
	mesh->addSubMesh(subMesh);
	//----model
	this->addMesh(mesh);
}
예제 #16
0
    //
    // Creates a cylinder at the origin oriented along the Z-axis.
    // 'innerRadius' represents the distance from the center to the inner ring.
    // innerRadius + thickness represents the distance from the center to the
    // outer rng.  'height' represents the amount to extrude along the Z-axis.
    // 'numStacks' is the number of layers along the Z-axis, 'numSlices' is
    // the number of radial divisions.
    //
    STShape* CreateThickCylinder(
        float innerRadius, float thickness, float height,
        unsigned int numSlices, unsigned int numStacks)
    {
        STShape* result = new STShape();

        //
        // Vertex packing
        //
        // 0 -> Slices * (Stacks + 1) - 1 = Inner ring
        // Slices * (Stacks + 1) -> Slices * (Stacks + 1) * 2 - 1 = Outer ring
        //
        // Face packing
        //
        // 0 -> Stacks * Slices * 2 - 1 = Inner ring
        // Stacks * Slices * 2 -> Stacks * Slices * 4 - 1 = Outer ring
        // Stacks * Slices * 4 -> Stacks * Slices * 4 - 1 = Connection between rings
        //

        const float ringRadii[2] = { innerRadius, innerRadius + thickness };
        const int ringVertexOffsets[2] = { 0, numSlices * (numStacks + 1) };

        const float PI2_Slices = 2.0f * float(M_PI) / float(numSlices);

        for (unsigned int ring = 0; ring < 2; ring++) {
            float ringRadius = ringRadii[ring];
            int ringVertexOffset = ringVertexOffsets[ring];

            for (unsigned int ii = 0; ii <= numStacks; ++ii) {
                for (unsigned int jj = 0; jj < numSlices; ++jj) {
                    const float theta = float(jj) * PI2_Slices;
                    STPoint3 position(ringRadius * cosf(theta),
                                      ringRadius * sinf(theta),
                                      height * (float(ii) / numStacks));
                    STPoint2 texCoord(ii / float(numStacks),
                                      jj / float(numSlices - 1));
                    result->AddVertex(
                        STShape::Vertex(position, STVector3::Zero, texCoord));
                }
            }

            for (unsigned int ii = 0; ii < numStacks; ++ii) {
                for(unsigned int jj = 0; jj < numSlices; jj++) {
                    int jjPlus1 = (jj + 1) % numSlices;

                    STShape::Face firstFace(
                        ringVertexOffset + (ii + 1)*numSlices + jj,
                        ringVertexOffset + (ii + 0)*numSlices + jj,
                        ringVertexOffset + (ii + 0)*numSlices + jjPlus1);
                    STShape::Face secondFace(
                        ringVertexOffset + (ii + 1)*numSlices + jj,
                        ringVertexOffset + (ii + 0)*numSlices + jjPlus1,
                        ringVertexOffset + (ii + 1)*numSlices + jjPlus1);

                    //
                    // The inner face points the opposite direciton
                    //
                    if (ring == 0) {
                        firstFace.ReverseWinding();
                        secondFace.ReverseWinding();
                    }

                    result->AddFace(firstFace);
                    result->AddFace(secondFace);
                }
            }
        }

        for (unsigned int ii = 0; ii <= numStacks; ii += numStacks) {
            for (unsigned int jj = 0; jj < numSlices; jj++) {
                int jjPlus1 = (jj + 1) % numSlices;

                STShape::Face firstFace(
                    ringVertexOffsets[0] + ii * numSlices + jj,
                    ringVertexOffsets[1] + ii * numSlices + jjPlus1,
                    ringVertexOffsets[1] + ii * numSlices + jj);
                STShape::Face secondFace(
                    ringVertexOffsets[0] + ii * numSlices + jj,
                    ringVertexOffsets[0] + ii * numSlices + jjPlus1,
                    ringVertexOffsets[1] + ii * numSlices + jjPlus1);

                //
                // The bottom face points the opposite direciton
                //
                if (ii == numStacks) {
                    firstFace.ReverseWinding();
                    secondFace.ReverseWinding();
                }

                result->AddFace(firstFace);
                result->AddFace(secondFace);
            }
        }

        result->GenerateNormals();
        return result;
    }
예제 #17
0
    bool Triangle::hit(const Ray& r, const real_t t0, const real_t t1, hitRecord& hR, bool fullRecord) const
    {
        Ray tRay = r.transform(invMat);

        real_t mult[3];

        Vector3 a_minus_b = vertices[0].position - vertices[1].position;
        Vector3 a_minus_c = vertices[0].position - vertices[2].position;
        Vector3 a_minus_e = vertices[0].position - tRay.e;

        real_t a = a_minus_b.x;
        real_t b = a_minus_b.y;
        real_t c = a_minus_b.z;
        real_t d = a_minus_c.x;
        real_t e = a_minus_c.y;
        real_t f = a_minus_c.z;
        real_t g = tRay.d.x;
        real_t h = tRay.d.y;
        real_t i = tRay.d.z;
        real_t j = a_minus_e.x;
        real_t k = a_minus_e.y;
        real_t l = a_minus_e.z;

        real_t ei_minus_hf = e * i - h * f;
        real_t gf_minus_di = g * f - d * i;
        real_t dh_minus_eg = d * h - e * g;
        real_t ak_minus_jb = a * k - j * b;
        real_t jc_minus_al = j * c - a * l;
        real_t bl_minus_kc = b * l - k * c;

        real_t M = a * ei_minus_hf + b * gf_minus_di + c * dh_minus_eg;
        real_t time = (f * ak_minus_jb + e * jc_minus_al + d * bl_minus_kc) / -M;
        if (time <= t0 || time >= t1) {
            return false;
        }

        real_t beta = (j * ei_minus_hf + k * gf_minus_di + l * dh_minus_eg) / M;
        if (beta < 0 || beta > 1)
            return false;

        real_t gamma = (i * ak_minus_jb + h * jc_minus_al + g * bl_minus_kc) / M;
        if (gamma < 0 || gamma > 1 - beta)
            return false;

        hR.t = time;
		hR.shape_ptr = (Geometry*)this;

        if (!fullRecord)
            return true;

        mult[0] = 1-beta-gamma;
        mult[1] = beta;
        mult[2] = gamma;

        Vector2 texCoord(0,0);
        for(int i=0;i<3;i++)
            texCoord += mult[i]*vertices[i].tex_coord;

        texCoord[0] = fmod(texCoord[0],1.0);
        texCoord[1] = fmod(texCoord[1],1.0);
        if(texCoord[0]<0) texCoord[0]+=1;
        if(texCoord[1]<0) texCoord[0]+=1;

        const Material* materials[] = { vertices[0].material,vertices[1].material,vertices[2].material };
        if(!simple)
            getMaterialProperties(hR.mp, mult, texCoord, materials);
        else
            getMaterialProperties(hR.mp,texCoord, materials[0]);

        hR.n = Vector3(0,0,0);
        for(int i=0;i<3;i++)
            hR.n += mult[i]*vertices[i].normal;
        hR.n = normalize( normMat*hR.n);

		if (materials[0])
			hR.bsdf_ptr = (BSDF*)&(materials[0]->bsdf);
		Vector3 x, y, z = hR.n;
		coordinate_system(z, &x, &y);
			
		hR.shading_trans = Matrix3(x, y, z);
		inverse(&hR.inv_shading_trans, hR.shading_trans);
		hR.p = r.d * time + r.e;

        return true;
    }
예제 #18
0
    void Triangle::hitPacket(const Packet& packet, int start, int end, real_t t0, real_t *t1Ptr, std::vector<hitRecord>& hs, bool fullRecord) const {
        /*Matrix4 nm = this->invMat;
        nm(3,0)=0;
        nm(3,1)=0;
        nm(3,2)=0;

        Ray rays[256];
        for(int i=start;i<end;i++)
        {
            rays[i] = packet.rays[i];
            packet.rays[i].transform(invMat);
        }*/
        // TODO: static
        float *texCoord_x, *texCoord_y, 
            *norm_x, *norm_y, *norm_z;

        texCoord_x = new float[end - start];
        texCoord_y = new float[end - start];
        norm_x = new float[end - start];
        norm_y = new float[end - start];
        norm_z = new float[end - start];

        int *hit_flag = new int[end - start];

        ispc::hit_triangle(packet.e_x, packet.e_y, packet.e_z, packet.d_x, packet.d_y, packet.d_z,
            t0, t1Ptr, 
            (double*)&vertices[0],(double*)&vertices[1],(double*)&vertices[2], (this->invMat._m),
            start, end, (int)fullRecord, 
            hit_flag, texCoord_x, texCoord_y, norm_x, norm_y, norm_z);
        const Material* materials[] = { vertices[0].material,vertices[1].material,vertices[2].material };

        for (int i = start; i < end; i++) {
            if (hit_flag[i - start]) {
                hs[i].t = t1Ptr[i];
                Vector2 texCoord(texCoord_x[i - start], texCoord_y[i - start]);

                // TODO: interpolation
                //if(!simple)
                //getMaterialProperties(hs[i].mp, mult, texCoord, materials);
                //else
                getMaterialProperties(hs[i].mp,texCoord, materials[0]);
                hs[i].n = Vector3(norm_x[i - start], norm_y[i - start], norm_z[i - start]);
				if (materials[0])
					hs[i].bsdf_ptr = (BSDF*)&(materials[0]->bsdf);
				Vector3 x, y, z = hs[i].n;
				coordinate_system(z, &x, &y);
			
				hs[i].shading_trans = Matrix3(x, y, z);
				inverse(&hs[i].inv_shading_trans, hs[i].shading_trans);
				hs[i].shape_ptr = (Geometry*)this;
				hs[i].p = packet.rays[i].d * hs[i].t + packet.rays[i].e;
            }
        }

        /*for(int i=start;i<end;i++)
             packet.rays[i]= rays[i];*/

        delete[] texCoord_x;
        delete[] texCoord_y;
        delete[] norm_x;
        delete[] norm_y;
        delete[] norm_z;
    }
예제 #19
0
Cc3dMeshData*genSampleCubeWithCode(float cx,float cy,float cz,float dx,float dy,float dz,
                                   float k_s,
                                   float k_t,
                                   int cubUVMode)
//用代码生成示例立方体
//cx,cy,cz为中心
//dx,dy,dz分别为x,y,z方向上的边心距
{
    Cc3dMeshData*meshData=new Cc3dMeshData();
    meshData->init();
    meshData->autorelease();
    meshData->vlist.reserve(8);
    meshData->IDtriList.reserve(12);
    //----生成顶点数据
    Cc3dVertex tv;
    //前面
    tv.setPos(Cc3dVector3(cx-dx, cy-dy,cz+dz));tv.setTexCoord(Cc3dVector2(0, 0));tv.setNorm(Cc3dVector3(0, 0, 1));//0
    meshData->vlist.push_back(tv);
    tv.setPos(Cc3dVector3(cx+dx, cy-dy,cz+dz));tv.setTexCoord(Cc3dVector2(1, 0));tv.setNorm(Cc3dVector3(0, 0, 1));//1
    meshData->vlist.push_back(tv);
    tv.setPos(Cc3dVector3(cx+dx, cy+dy, cz+dz));tv.setTexCoord(Cc3dVector2(1, 1));tv.setNorm(Cc3dVector3(0, 0, 1));//2
    meshData->vlist.push_back(tv);
    tv.setPos(Cc3dVector3(cx-dx, cy+dy, cz+dz));tv.setTexCoord(Cc3dVector2(0, 1));tv.setNorm(Cc3dVector3(0, 0, 1));//3
    meshData->vlist.push_back(tv);
    //后面
    tv.setPos(Cc3dVector3(cx-dx, cy-dy,cz -dz));tv.setTexCoord(Cc3dVector2(0, 0));tv.setNorm(Cc3dVector3(0, 0, -1));//4
    meshData->vlist.push_back(tv);
    tv.setPos(Cc3dVector3(cx+dx, cy-dy, cz-dz));tv.setTexCoord(Cc3dVector2(1, 0));tv.setNorm(Cc3dVector3(0, 0, -1));//5
    meshData->vlist.push_back(tv);
    tv.setPos(Cc3dVector3(cx+dx, cy+dy, cz-dz));tv.setTexCoord(Cc3dVector2(1, 1));tv.setNorm(Cc3dVector3(0, 0, -1));//6
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy+dy, cz-dz);tv.setTexCoord(0, 1);tv.setNorm(0, 0, -1);//7
    meshData->vlist.push_back(tv);
    //上面
    tv.setPos(cx-dx, cy+dy, cz+dz);tv.setTexCoord(0, 0);tv.setNorm(0, 1, 0);//8
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy+dy, cz+dz);tv.setTexCoord(1, 0);tv.setNorm(0, 1, 0);//9
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy+dy, cz-dz);tv.setTexCoord(1, 1);tv.setNorm(0, 1, 0);//10
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy+dy, cz-dz);tv.setTexCoord(0, 1);tv.setNorm(0, 1, 0);//11
    meshData->vlist.push_back(tv);
    //下面
    tv.setPos(cx-dx, cy-dy, cz+dz);tv.setTexCoord(0, 0);tv.setNorm(0, -1, 0);//12
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy-dy, cz+dz);tv.setTexCoord(1, 0);tv.setNorm(0, -1, 0);//13
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy-dy, cz-dz);tv.setTexCoord(1, 1);tv.setNorm(0, -1, 0);//14
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy-dy, cz-dz);tv.setTexCoord(0, 1);tv.setNorm(0, -1, 0);//15
    meshData->vlist.push_back(tv);
    //左面
    tv.setPos(cx-dx, cy-dy,cz -dz);tv.setTexCoord(0, 0);tv.setNorm(-1, 0, 0);//16
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy-dy, cz+dz);tv.setTexCoord(1, 0);tv.setNorm(-1, 0, 0);//17
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy+dy, cz+dz);tv.setTexCoord(1, 1);tv.setNorm(-1, 0, 0);//18
    meshData->vlist.push_back(tv);
    tv.setPos(cx-dx, cy+dy, cz-dz);tv.setTexCoord(0, 1);tv.setNorm(-1, 0, 0);//19
    meshData->vlist.push_back(tv);
    //右面
    tv.setPos(cx+dx, cy-dy, cz-dz);tv.setTexCoord(0, 0);tv.setNorm(1, 0, 0);//20
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy-dy,cz+ dz);tv.setTexCoord(1, 0);tv.setNorm(1, 0, 0);//21
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy+dy, cz+dz);tv.setTexCoord(1, 1);tv.setNorm(1, 0, 0);//22
    meshData->vlist.push_back(tv);
    tv.setPos(cx+dx, cy+dy, cz-dz);tv.setTexCoord(0, 1);tv.setNorm(1, 0, 0);//23
    meshData->vlist.push_back(tv);
    //----生成索引三角形
    Cc3dIDTriangle tIDtri;
    //前面
    tIDtri.setvID(0, 1, 2);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(0, 2, 3);
    meshData->IDtriList.push_back(tIDtri);
    //后面
    tIDtri.setvID(4, 6, 5);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(4, 7, 6);
    meshData->IDtriList.push_back(tIDtri);
    //上面
    tIDtri.setvID(8, 9, 10);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(8, 10, 11);
    meshData->IDtriList.push_back(tIDtri);
    //下面
    tIDtri.setvID(12, 14, 13);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(12, 15, 14);
    meshData->IDtriList.push_back(tIDtri);
    //左面
    tIDtri.setvID(16, 17, 18);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(16, 18, 19);
    meshData->IDtriList.push_back(tIDtri);
    //右面
    tIDtri.setvID(20, 22, 21);
    meshData->IDtriList.push_back(tIDtri);
    tIDtri.setvID(20, 23, 22);
    meshData->IDtriList.push_back(tIDtri);
    //----重新计算各三角形各顶点的uv
    int nv=(int)meshData->vlist.size();
    vector<bool> markList(nv);//标记各顶点是否已经重计算过uv,避免多次计算(多次计算可能导致出错),初始全0
    int nIDtri=(int)meshData->IDtriList.size();
    for(int i=0;i<nIDtri;i++){
        Cc3dIDTriangle&IDtri=meshData->IDtriList[i];
        //重新计算IDtri各顶点的uv
        switch(cubUVMode)
        {
            case cubUVMode_FITFACE:
            {
                //将IDtri中未mark的顶点的uv分别乘以k_s,k_t
                for(int j=0;j<3;j++){
                    int vID=IDtri.vID[j];//顶点号
                    if(markList[vID]==false){//未计算过
                        //重新计算
                        Cc3dVertex&v=meshData->vlist[vID];
                        Cc3dVector2 texCoord=v.getTexCoord();
                        texCoord.setx(texCoord.x()*k_s);
                        texCoord.sety(texCoord.y()*k_t);
                        v.setTexCoord(texCoord);
                        markList[vID]=true;//标记为已计算
                    }
                }
            }break;
            case cubUVMode_UNIFORM:
            {
                //将IDtri各顶点的uv,重新按顶点坐标来计算,并以k_s,k_t放缩
                //判断IDtri的类型
                const int type_LR=0;//左或右
                const int type_UD=1;//上或下
                const int type_FB=2;//前或后
                int type=0;
                Cc3dVector3 norm=meshData->vlist[IDtri.vID[0]].getNorm();
                if(fabsf(fabsf(norm.x())-1)<0.01){//左面或右面
                    type=type_LR;
                }else if(fabsf(fabsf(norm.y())-1)<0.01){//上面或下面
                    type=type_UD;
                }else{//前面或后面
                    type=type_FB;
                }//得到type
                for(int j=0;j<3;j++){
                    int vID=IDtri.vID[j];//顶点号
                    if(markList[vID]==false){//未计算过
                        //重新计算
                        Cc3dVertex&v=meshData->vlist[vID];
                        switch (type) {
                            case type_LR:{
                                //用yz
                                Cc3dVector2 texCoord(v.getPos().y()*k_s,v.getPos().z()*k_t);
                                v.setTexCoord(texCoord);
                            }break;
                            case type_UD:{
                                //用xz
                                Cc3dVector2 texCoord(v.getPos().x()*k_s,v.getPos().z()*k_t);
                                v.setTexCoord(texCoord);
                            }break;
                            case type_FB:{
                                //用xy
                                Cc3dVector2 texCoord(v.getPos().x()*k_s,v.getPos().y()*k_t);
                                v.setTexCoord(texCoord);
                            }break;
                        }
                        //标记为已计算
                        markList[vID]=true;
                    }
                }
            }break;
            default:
                cout<<"error:未知的cubUV映射类型!"<<endl;
                assert(false);
                break;
        }
        
        
    }
    return meshData;
    
}
예제 #20
0
	bool AssimpLoadMesh(const Ptr<MeshAsset> & asset, bool bFlipUV, bool bLeftHanded)
	{
		if (!Global::GetPlatform()->FileExists(asset->GetLoadPath()))
		{
			ToyGE_LOG(LT_WARNING, "Cannot open mesh file when reading! %s", asset->GetLoadPath().c_str());
			return false;
		}

		auto meshFullPath = asset->GetLoadFullPath();
		auto meshDirFullPath = ParentPath(meshFullPath);
		auto assetsFullBasePath = Global::GetPlatform()->GetPathFullName(Asset::GetAssetsBasePath());
		String meshDirRelativePath;
		if (!Global::GetPlatform()->GetRelativePath(assetsFullBasePath, true, meshDirFullPath, true, meshDirRelativePath))
		{
			ToyGE_LOG(LT_WARNING, "Cannot find relative path for mesh from %s to %s!", assetsFullBasePath.c_str(), meshDirFullPath.c_str());
			return false;
		}

		// Base path for mesh's resources
		String basePath = meshDirRelativePath;

		uint32_t processFlag = aiProcessPreset_TargetRealtime_Quality;// | aiProcess_MakeLeftHanded;
		if (bFlipUV)
			processFlag |= aiProcess_FlipUVs;
		if (bLeftHanded)
			processFlag |= aiProcess_MakeLeftHanded;

		Assimp::Importer importer;
		const aiScene *pAiScene = importer.ReadFile(asset->GetLoadPath(), processFlag);
		if (nullptr == pAiScene)
		{
			ToyGE_LOG(LT_WARNING, "Cannot load mesh! %s", asset->GetLoadPath().c_str());
			return false;
		}


		// Material
		std::vector<Ptr<MaterialAsset>> materials;

		for (uint32_t matIndex = 0; matIndex != pAiScene->mNumMaterials; ++matIndex)
		{
			Ptr<MaterialAsset> mat = std::make_shared<MaterialAsset>();
			const aiMaterial *pAiMat = pAiScene->mMaterials[matIndex];

			// Diffuse
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_DIFFUSE); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_DIFFUSE, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;

				if(basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_BASECOLOR, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_BASECOLOR, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			// Specular
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_SPECULAR); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_SPECULAR, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;
				//mat->AddTexture(MaterialTextureType::MAT_TEX_METALLIC, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), uvIndex);
				if (basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_METALLIC, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_METALLIC, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			// Normal
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_NORMALS); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_NORMALS, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;
				//mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), uvIndex);
				if (basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			// Height
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_HEIGHT); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_HEIGHT, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;
				//mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), uvIndex);
				if (basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_BUMP, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			// Roughness
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_SHININESS); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_SHININESS, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;


				if (basePath.size() > 0)
				{
					auto roughnessPath = ShininessToRoughnessTex(basePath + "/" + path.C_Str());
					mat->AddTexture(MaterialTextureType::MAT_TEX_ROUGHNESS, Asset::Find<TextureAsset>(roughnessPath), static_cast<uint8_t>(uvIndex));
				}
				else
				{
					auto roughnessPath = ShininessToRoughnessTex(path.C_Str());
					mat->AddTexture(MaterialTextureType::MAT_TEX_ROUGHNESS, Asset::Find<TextureAsset>(roughnessPath), static_cast<uint8_t>(uvIndex));
				}
			}

			// Opacity
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_OPACITY); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_OPACITY, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;
				//mat->AddTexture(MAT_TEX_OPACITYMASK, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), 0);
				if (basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_OPACITYMASK, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_OPACITYMASK, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			// EMISSIVE
			for (uint32_t texIndex = 0; texIndex != pAiMat->GetTextureCount(aiTextureType_EMISSIVE); ++texIndex)
			{
				aiString path;
				uint32_t uvIndex;
				pAiMat->GetTexture(aiTextureType_EMISSIVE, texIndex, &path, 0, &uvIndex);
				if (uvIndex >= MaxNumTexCoord::NUM)
					uvIndex = 0;
				//mat->AddTexture(MAT_TEX_EMISSIVE, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), 0);
				if (basePath.size() > 0)
					mat->AddTexture(MaterialTextureType::MAT_TEX_EMISSIVE, Asset::Find<TextureAsset>(basePath + "/" + path.C_Str()), static_cast<uint8_t>(uvIndex));
				else
					mat->AddTexture(MaterialTextureType::MAT_TEX_EMISSIVE, Asset::Find<TextureAsset>(path.C_Str()), static_cast<uint8_t>(uvIndex));
			}

			aiColor3D baseColor;
			pAiMat->Get(AI_MATKEY_COLOR_DIFFUSE, baseColor);
			mat->SetBaseColor(float3(baseColor.r, baseColor.g, baseColor.b));

			float opacity;
			pAiMat->Get(AI_MATKEY_OPACITY, opacity);
			mat->SetOpcacity(opacity);

			float shininess;
			pAiMat->Get(AI_MATKEY_SHININESS, shininess);
			mat->SetRoughness(pow(2.0f / (shininess + 2.0f), 0.25f));

			// Set material path
			aiString matName;
			pAiMat->Get(AI_MATKEY_NAME, matName);
			if (matName.length > 0)
			{
				if(basePath.size() > 0)
					mat->SetPath(basePath + "/Material/" + matName.C_Str() + MaterialAsset::GetExtension());
				else
					mat->SetPath(String("Material/") + matName.C_Str() + MaterialAsset::GetExtension());
			}
			else
			{
				if (basePath.size() > 0)
					mat->SetPath(basePath + "/Material/mat_" + std::to_string(matIndex) + MaterialAsset::GetExtension());
				else
					mat->SetPath(String("Material/mat_") + matName.C_Str() + MaterialAsset::GetExtension());
			}

			materials.push_back(mat);
		}


		// Mesh
		std::vector<Ptr<MeshElement>> meshElements;

		for (uint32_t meshIndex = 0; meshIndex != pAiScene->mNumMeshes; ++meshIndex)
		{
			Ptr<MeshElement> meshElement = std::make_shared<MeshElement>();
			const aiMesh *pAiMesh = pAiScene->mMeshes[meshIndex];

			meshElement->material = materials[pAiMesh->mMaterialIndex];

			auto vertexSlot = std::make_shared<MeshVertexSlotData>();
			//meshElement->vertexData = std::make_shared<MeshVertexData>();

			// Init vertex elements desc
			std::vector<MeshVertexElementDesc> & elementsDesc = vertexSlot->vertexDesc.elementsDesc;
			MeshVertexElementDesc elemDesc;
			int32_t bytesOffset = 0;
			if (pAiMesh->HasPositions())
			{
				elemDesc.signature = MeshVertexElementSignature::MVET_POSITION;
				elemDesc.signatureIndex = 0;
				elemDesc.bytesOffset = bytesOffset;
				elemDesc.bytesSize = static_cast<int32_t>(sizeof(float3));
				elementsDesc.push_back(elemDesc);
				bytesOffset += elemDesc.bytesSize;
			}

			if (pAiMesh->GetNumUVChannels() > 0)
			{
				for (uint32_t uvChannel = 0; uvChannel != pAiMesh->GetNumUVChannels(); ++uvChannel)
				{
					elemDesc.signature = MeshVertexElementSignature::MVET_TEXCOORD;
					elemDesc.signatureIndex = static_cast<int32_t>(uvChannel);
					elemDesc.bytesOffset = bytesOffset;
					elemDesc.bytesSize = static_cast<int32_t>(sizeof(float3));
					elementsDesc.push_back(elemDesc);
					bytesOffset += elemDesc.bytesSize;
				}
			}

			if (pAiMesh->HasNormals())
			{
				elemDesc.signature = MeshVertexElementSignature::MVET_NORMAL;
				elemDesc.signatureIndex = 0;
				elemDesc.bytesOffset = bytesOffset;
				elemDesc.bytesSize = static_cast<int32_t>(sizeof(float3));
				elementsDesc.push_back(elemDesc);
				bytesOffset += elemDesc.bytesSize;
			}

			if (pAiMesh->HasTangentsAndBitangents())
			{
				elemDesc.signature = MeshVertexElementSignature::MVET_TANGENT;
				elemDesc.signatureIndex = 0;
				elemDesc.bytesOffset = bytesOffset;
				elemDesc.bytesSize = static_cast<int32_t>(sizeof(float3));
				elementsDesc.push_back(elemDesc);
				bytesOffset += elemDesc.bytesSize;

				elemDesc.signature = MeshVertexElementSignature::MVET_BITANGENT;
				elemDesc.signatureIndex = 0;
				elemDesc.bytesOffset = bytesOffset;
				elemDesc.bytesSize = static_cast<int32_t>(sizeof(float3));
				elementsDesc.push_back(elemDesc);
				bytesOffset += elemDesc.bytesSize;
			}

			vertexSlot->vertexDesc.bytesSize = bytesOffset;

			// Init vertex data
			int32_t stride = bytesOffset;
			vertexSlot->bufferSize = stride * static_cast<int32_t>(pAiMesh->mNumVertices);
			vertexSlot->rawBuffer = MakeBufferedDataShared(static_cast<size_t>(vertexSlot->bufferSize));

			bytesOffset = 0;
			uint8_t * data = vertexSlot->rawBuffer.get();
			if (pAiMesh->HasPositions())
			{
				for (uint32_t vertexIndex = 0; vertexIndex != pAiMesh->mNumVertices; ++vertexIndex)
				{
					float3 pos;
					pos.x() = pAiMesh->mVertices[vertexIndex].x;
					pos.y() = pAiMesh->mVertices[vertexIndex].y;
					pos.z() = pAiMesh->mVertices[vertexIndex].z;
					memcpy(data, &pos, sizeof(pos));
					data += stride;
				}
				bytesOffset += static_cast<int32_t>(sizeof(float3));
			}

			if (pAiMesh->GetNumUVChannels() > 0)
			{
				data = vertexSlot->rawBuffer.get() + bytesOffset;
				for (uint32_t vertexIndex = 0; vertexIndex != pAiMesh->mNumVertices; ++vertexIndex)
				{
					for (uint32_t uvChannel = 0; uvChannel != pAiMesh->GetNumUVChannels(); ++uvChannel)
					{
						auto & uvw = pAiMesh->mTextureCoords[uvChannel][vertexIndex];
						float3 texCoord(uvw.x, uvw.y, uvw.z);
						memcpy(data + sizeof(texCoord) * uvChannel, &texCoord, sizeof(texCoord));
					}
					data += stride;
				}
				bytesOffset += static_cast<int32_t>(sizeof(float3) * pAiMesh->GetNumUVChannels());
			}

			if (pAiMesh->HasNormals())
			{
				data = vertexSlot->rawBuffer.get() + bytesOffset;
				for (uint32_t vertexIndex = 0; vertexIndex != pAiMesh->mNumVertices; ++vertexIndex)
				{
					float3 normal;
					normal.x() = pAiMesh->mNormals[vertexIndex].x;
					normal.y() = pAiMesh->mNormals[vertexIndex].y;
					normal.z() = pAiMesh->mNormals[vertexIndex].z;
					normal = normalize(normal);
					memcpy(data, &normal, sizeof(normal));
					data += stride;
				}
				bytesOffset += static_cast<int32_t>(sizeof(float3));
			}

			if (pAiMesh->HasTangentsAndBitangents())
			{
				data = vertexSlot->rawBuffer.get() + bytesOffset;
				for (uint32_t vertexIndex = 0; vertexIndex != pAiMesh->mNumVertices; ++vertexIndex)
				{
					float3 tangent;
					tangent.x() = pAiMesh->mTangents[vertexIndex].x;
					tangent.y() = pAiMesh->mTangents[vertexIndex].y;
					tangent.z() = pAiMesh->mTangents[vertexIndex].z;
					memcpy(data, &tangent, sizeof(tangent));

					float3 bitangent;
					bitangent.x() = pAiMesh->mBitangents[vertexIndex].x;
					bitangent.y() = pAiMesh->mBitangents[vertexIndex].y;
					bitangent.z() = pAiMesh->mBitangents[vertexIndex].z;
					memcpy(data + sizeof(tangent), &bitangent, sizeof(bitangent));

					data += stride;
				}
				bytesOffset += static_cast<int32_t>(sizeof(float3));
			}
			meshElement->vertexData.push_back(vertexSlot);

			// Indices
			for (uint32_t faceIndex = 0; faceIndex != pAiMesh->mNumFaces; ++faceIndex)
			{
				aiFace &pAiFace = pAiMesh->mFaces[faceIndex];
				for (uint32_t index = 0; index != pAiFace.mNumIndices; ++index)
					meshElement->indices.push_back(pAiFace.mIndices[index]);
			}

			meshElements.push_back(meshElement);
		}
		asset->SetData(meshElements);

		return true;
	}
// отрисовка из прошлой лабы, только берём цвета из текстуры
void Triangle::draw(Canvas& canvas, Texture* texture = 0) {
    std::vector<TexturedPoint> points;

    // преобразование и упорядочивание по x
    transform(points);
    std::sort(points.begin(), points.end());

    std::vector<Edge> edges;

    // установка границ
    int minY = (points.front().y() < 0) ? 0: points.front().y();
    int maxY = (points.back().y() < this->maxY) ? points.back().y() : this->maxY - 1;

    int curY = minY;
    int i = 0;

    while (curY < maxY) {
        int nextY = maxY;

        while ( i != (int)points.size() && trunc( points[i].y()) <= curY ){
            TexturedPoint a = points[i];
            TexturedPoint b = points[(points.size() - i - 1 ) % points.size()];
            TexturedPoint c = points[(i + 1) % points.size()];

            if (b.y() > curY ) {
                edges.push_back(Edge(a,b));
                if ( b.y() < nextY ) {
                    nextY = b.y() ;
                }
            }
            if (c.y() > curY) {
                edges.push_back(Edge(a,c));
                if ( c.y() < nextY) {
                    nextY = c.y();
                }
            }
            ++i;
        }

        while(curY <= nextY && curY <= maxY) {

            std::vector<TexturedPoint> borderX;
            for (int i = 0; i < (int)edges.size(); ++i) {
                int n = curY - edges[i].getA().y();
                double curX = (edges[i].getA().x()) + n * edges[i].getK();
                TexturedPoint texCoord(curX, curY);
                texCoord.calcTextureCoordinates(edges[i].getA(), edges[i].getB());
                borderX.push_back(texCoord);
            }

            std::sort(borderX.begin(), borderX.end(), TexturedPoint::compX);
            int begin = borderX.front().x() > 0 ? borderX.front().x() : 0;

            for (int x = begin; x < borderX.back().x() && x < maxX; ++x) {
                TexturedPoint curPoint(x, curY);

                curPoint.calcTextureCoordinates(borderX.front(),borderX.back());

                if (0 == texture) {
                    // если текстуры нет( то как градиент )
                    canvas.drawPixel(x, curY, TexturedPoint::transformToColor(curPoint.getTexX(), curPoint.getTexY()));
                } else {
                    canvas.drawPixel(x, curY, texture->get_color(curPoint));
                }
            }

            ++curY;
        }

        std::vector<Edge>::iterator iter = edges.begin();
        while (iter != edges.end()) {
           if ( (*iter).getB().y() < curY) {
               edges.erase(iter);
           }
           else {
               ++iter;
           }
        }

   }
}
예제 #22
0
파일: MD2Loader.cpp 프로젝트: jetSett/yage
Model* MD2Loader::loadFromFile(const std::string& name) {
    std::ifstream stream(name.c_str(), std::ios_base::binary);
    Header head;
    stream.read(reinterpret_cast<char*>(&head), sizeof(Header));

    if(head.magic != _magicId)
        throw LoadingFailed(name + " magic");
    if(head.version != _MD2Version)
        throw LoadingFailed(name + " version");
    std::vector<Texture> textures(head.nbTex);
    std::vector<TexCoord> texCoord(head.nbTexCoord);
    std::vector<Triangle> triangles(head.nbTriangles);
    std::vector<Frame> frames(head.nbFrames);

    stream.seekg(head.offsetTextures, std::ios_base::beg);
    stream.read(reinterpret_cast<char*>(&textures[0]), sizeof(Texture)*head.nbTex);

    stream.seekg(head.offsetTexCoords, std::ios_base::beg);
    stream.read(reinterpret_cast<char*>(&texCoord[0]), sizeof(TexCoord)*head.nbTexCoord);

    stream.seekg(head.offsetTriangles, std::ios_base::beg);
    stream.read(reinterpret_cast<char*>(&triangles[0]), sizeof(Triangle)*head.nbTriangles);

    stream.seekg(head.offsetFrames, std::ios_base::beg);
    frames[0].vertices.resize(head.nbVert);
    stream.read(reinterpret_cast<char*>(&frames[0].scale), sizeof(frames[0].scale));
    stream.read(reinterpret_cast<char*>(&frames[0].translate), sizeof(frames[0].translate));
    stream.read(reinterpret_cast<char*>(&frames[0].name), sizeof(frames[0].name));
    stream.read(reinterpret_cast<char*>(&frames[0].vertices[0]), sizeof(Point)*head.nbVert);

    std::vector<Model::Vertex> vertices;
    std::vector<Model::Index>  indices;

    for(int i = 0; i < head.nbTriangles; ++i) {
        for(int j=0; j<3; ++j) {
            Model::Vertex v;
            const Point& vert = frames[0].vertices[triangles[i].vertices[j]];
            const TexCoord& texC = texCoord[triangles[i].texCoords[j]];

            v.px = vert.x*frames[0].scale.x+frames[0].translate.x;
            v.py = vert.y*frames[0].scale.y+frames[0].translate.y;
            v.pz = vert.z*frames[0].scale.z+frames[0].translate.z;

            v.nx = _normalTable[vert.n].x;
            v.ny = _normalTable[vert.n].y;
            v.nz = _normalTable[vert.n].z;

            v.color = Graphics::D3::Renderer::getInstance().convertColor(Graphics::Color::White);

            v.tx = texC.u/static_cast<float>(head.texW);
            v.ty = texC.v/static_cast<float>(head.texH);

            vertices.push_back(v);
            indices.push_back(i*3+2-j);
        }
    }

    std::string texName = "";

    if(textures[0].name != nullptr)
        texName = textures[0].name;
    Model* m = new Model(name, &vertices[0], (int)vertices.size(), &indices[0], (int)indices.size(), texName);
    return m;
}
예제 #23
0
파일: decal.cpp 프로젝트: yushiming/CS
void csDecal::AddStaticPoly (const csPoly3D & p, csArray<size_t>* indices)
{
    CS_ASSERT(animationControlData.animationControl ?
              indices != (csArray<size_t>*) nullptr : 1);

    if (!currMesh)
        return;

    size_t a;
    CS::TriangleT<int> tri;
    csPoly3D poly = p;

    if (decalTemplate->HasClipping ())
        for (a = 0; a < numClipPlanes; ++a)
            CutPolyToPlane (poly, clipPlanes[a], indices);

    size_t vertCount = poly.GetVertexCount ();

    // only support triangles and up
    if (vertCount < 3)
        return;

    // ensure the polygon isn't facing away from the decal's normal too much
    csVector3 polyNorm = poly.ComputeNormal ();
    float polyNormThresholdValue = -polyNorm * localNormal;
    if (polyNormThresholdValue < decalTemplate->GetPolygonNormalThreshold ())
        return;

    // check if we hit our maximum allowed vertices
    if (vertexCount + vertCount > CS_DECAL_MAX_VERTS_PER_DECAL)
        vertCount = CS_DECAL_MAX_VERTS_PER_DECAL - vertexCount;

    if (vertCount < 3)
        return;

    // check if we hit our maximum allowed indices
    size_t idxCount = (vertCount - 2) * 3;
    if (indexCount + idxCount > CS_DECAL_MAX_TRIS_PER_DECAL * 3)
        return;

    // if this face is too perpendicular, then we'll need to push it out a bit
    // to avoid z-fighting.  We do this by pushing the bottom of the face out
    // more than the top of the face
    bool doFaceOffset = false;
    float faceHighDot = 0.0f;
    float invHighLowFaceDist = 0.0f;
    csVector3 faceBottomOffset(0.0f);
    csVector3 faceCenter(0.0f);
    if (decalTemplate->HasClipping () && !animationControlData.animationControl)
    {
        if (fabs (polyNormThresholdValue)
                < decalTemplate->GetPerpendicularFaceThreshold ())
        {
            doFaceOffset = true;

            csVector3 faceHighVert, faceLowVert;
            float faceLowDot;

            faceLowVert = faceHighVert = *poly.GetVertex (0);
            faceLowDot = faceHighDot = (faceLowVert - relPos) * localNormal;
            faceCenter = faceLowVert;
            for (a = 1; a < vertCount; ++a)
            {
                const csVector3 * vertPos = poly.GetVertex (a);
                faceCenter += *vertPos;
                float dot = (*vertPos - relPos) * localNormal;
                if (dot > faceHighDot)
                {
                    faceHighVert = *vertPos;
                    faceHighDot = dot;
                }
                if (dot < faceLowDot)
                {
                    faceLowVert = *vertPos;
                    faceLowDot = dot;
                }
            }
            invHighLowFaceDist = 1.0f / (faceHighDot - faceLowDot);
            faceBottomOffset = -decalTemplate->GetPerpendicularFaceOffset () * polyNorm;
            faceCenter /= (float)vertCount;
        }
    }

    const csVector2 & minTexCoord = decalTemplate->GetMinTexCoord ();
    csVector2 texCoordRange = decalTemplate->GetMaxTexCoord () - minTexCoord;

    tri[0] = (int)vertexCount;
    for (a = 0; a < vertCount; ++a)
    {
        csVector3 vertPos = *poly.GetVertex (a);
        float distToPos = (vertPos - relPos) * localNormal;

        if (decalTemplate->HasClipping () && !animationControlData.animationControl)
        {
            if (doFaceOffset)
            {
                // linear interpolation where high vert goes nowhere and low vert is
                // full offset
                float offsetVal = (faceHighDot - distToPos) * invHighLowFaceDist;
                vertPos += offsetVal * faceBottomOffset;

                // spread out the base to avoid vertical seams
                vertPos += (vertPos - faceCenter).Unit ()
                           * (decalTemplate->GetPerpendicularFaceOffset () * 2.0f);
            }
        }

        vertPos += vertOffset;

        csVector3 relVert = vertPos - relPos;
        size_t vertIdx = vertexCount+a;

        // copy over vertex data
        vertexBuffer->CopyInto (&vertPos, 1, vertIdx);

        // copy over color
        csColor4 color;
        if (-distToPos >= 0.0f)
        {
            float t = 0.0f;
            if (topPlaneDist >= 0.01f)
                t = -distToPos / topPlaneDist;
            color = decalTemplate->GetMainColor () * (1.0f - t) +
                    decalTemplate->GetTopColor () * t;
        }
        else
        {
            float t = 0.0f;
            if (bottomPlaneDist >= 0.01f)
                t = distToPos / bottomPlaneDist;
            color = decalTemplate->GetMainColor () * (1.0f - t) +
                    decalTemplate->GetBottomColor () * t;
        }
        colorBuffer->CopyInto (&color, 1, vertIdx);

        // create the index buffer for each triangle in the poly
        if (a >= 2)
        {
            tri[1] = (int)vertIdx-1;
            tri[2] = (int)vertIdx;
            indexBuffer->CopyInto (&tri, 3, indexCount);
            indexCount += 3;
        }

        // generate uv coordinates
        csVector2 texCoord ( minTexCoord.x + texCoordRange.x * 0.5f +
                             texCoordRange.x * localRight * invWidth * relVert,
                             minTexCoord.y + texCoordRange.y * 0.5f -
                             texCoordRange.y * localUp * invHeight * relVert);
        texCoordBuffer->CopyInto (&texCoord, 1, vertIdx);

        // TODO: compute tangents/binormals

        // copy over normal
        normalBuffer->CopyInto (&localNormal, 1, vertIdx);
    }

    vertexCount += vertCount;

    if (indices)
        animationControlData.animatedIndices.Merge (*indices);
}
//-------------------------------------------------------------------------
FKCW_3D_Mesh* CreateConeMesh(float r,float h,int nSlice,int nStack,bool isHaveBottom,
							const FKCW_3D_Vector4&headColor,const FKCW_3D_Vector4&bottomColor)
	//why cone need nStack ? because even a plane need subdivision to achieve better specular effect
{
	float dA=360.0f/nSlice;
	const float PIDIV180= static_cast<float>(M_PI/180.0f);
	vector<FKCW_3D_Vector4> positionList;
	vector<FKCW_3D_Vector2> texCoordList;
	vector<FKCW_3D_Vector4> normalList;
	vector<FKCW_3D_Vector4> colorList;
	vector<FKCW_3D_IDTriangle> IDtriList;
	//----generate side
	//generate positionList, texCoordList, normalList, colorList
	for(int i=0;i<=nStack;i++){
		float y=i*h/nStack;
		for (int j=0; j<=nSlice; j++) {
			float A=j*dA;
			float R=r-i*r/nStack;
			float cosA=cosf(A*PIDIV180);
			float sinA=sinf(A*PIDIV180);
			float x=R*cosA;
			float z=R*sinA;
			FKCW_3D_Vector4 position(x,y,z,1);
			float s=(float)j/nSlice+0.25f;
			float t=1-(float)i/nStack;
			FKCW_3D_Vector2 texCoord(s,t);
			float ny=r/sqrtf(FKCW_Square(h)+FKCW_Square(r));
			float nx,nz;//nx*nx+ny*ny+nz*nz=1 and nx:nz=cosA:sinA => k=sqrt((1-ny*ny)/(cosA*cosA+sinA*sinA)), nx=cosA*k, nz=sinA*k
			float k=sqrtf((1-ny*ny)/(cosA*cosA+sinA*sinA));
			nx=cosA*k;
			nz=sinA*k;
			FKCW_3D_Vector4 normal=normalize(FKCW_3D_Vector4(nx,ny,nz,0));
			FKCW_3D_Vector4 color=bottomColor*(1-(float)i/nStack)+headColor*((float)i/nStack);
			positionList.push_back(position);
			texCoordList.push_back(texCoord);
			normalList.push_back(normal);
			colorList.push_back(color);
		}
	}
	//generate IDtriList
	for(int i=0;i<nStack;i++){
		for(int j=0;j<nSlice;j++){
			int vID_ld=(nSlice+1)*i+j;
			int vID_rd=vID_ld+1;
			int vID_ru=vID_rd+(nSlice+1);
			int vID_lu=vID_ru-1;
			FKCW_3D_IDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
			FKCW_3D_IDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
			IDtriList.push_back(IDtri0);
			IDtriList.push_back(IDtri1);
		}
	}

	//----generate bottom
	if(isHaveBottom){
		vector<FKCW_3D_Vector4> _positionList=positionList;
		vector<FKCW_3D_Vector2> _texCoordList=texCoordList;
		vector<FKCW_3D_Vector4> _normalList=normalList;
		vector<FKCW_3D_Vector4> _colorList=colorList;
		vector<FKCW_3D_IDTriangle> _IDtriList=IDtriList;
		//all postion in _positionList set y to zero
		int _nPosition=(int)_positionList.size();
		for(int i=0;i<_nPosition;i++){
			FKCW_3D_Vector4&position=_positionList[i];
			position.sety(0);
		}
		//all normal in _normalList set to (0,-1,0,0)
		int _nNormal=(int)_normalList.size();
		for(int i=0;i<_nNormal;i++){
			FKCW_3D_Vector4&normal=_normalList[i];
			normal=FKCW_3D_Vector4(0, -1, 0, 0);
		}
		//all index in _IDtriList should be plus offset=(int)positionList.size()
		const int offset=(int)positionList.size();
		int _nIDtri=(int)_IDtriList.size();
		for(int i=0;i<_nIDtri;i++){
			FKCW_3D_IDTriangle&IDtri=_IDtriList[i];
			int ID0=IDtri.vID(0);
			int ID1=IDtri.vID(1);
			int ID2=IDtri.vID(2);
			IDtri.init(ID0+offset, ID1+offset, ID2+offset);
		}
		//connect side and bottom
		positionList=connectList(positionList,_positionList);
		texCoordList=connectList(texCoordList,_texCoordList);
		normalList=connectList(normalList,_normalList);
		colorList=connectList(colorList,_colorList);
		IDtriList=connectList(IDtriList,_IDtriList);
	}

	//----create mesh
	FKCW_3D_SubMeshData*subMeshData=new FKCW_3D_SubMeshData();
	subMeshData->autorelease();
	subMeshData->init();
	subMeshData->initPositionList(positionList);
	subMeshData->initTexCoordList(texCoordList);
	subMeshData->initNormalList(normalList);
	subMeshData->initColorList(colorList);
	subMeshData->initIDtriList(IDtriList);
	FKCW_3D_SubMesh* subMesh=new FKCW_3D_SubMesh();
	subMesh->autorelease();
	subMesh->init();
	subMesh->setSubMeshData(subMeshData);
	FKCW_3D_Mesh* mesh=new FKCW_3D_Mesh();
	mesh->autorelease();
	mesh->init();
	mesh->addSubMesh(subMesh);
	return mesh;
}
//-------------------------------------------------------------------------
FKCW_3D_Mesh* CreateBallMesh(float r,int nSlice,int nStack,
							const FKCW_3D_Vector4&northPoleColor,const FKCW_3D_Vector4&southPoleColor)
{
	float dA=360.0f/nSlice;
	float dB=180.0f/nStack;
	const float PIDIV180=static_cast<float>(M_PI/180.0f);
	vector<FKCW_3D_Vector4> positionList;
	vector<FKCW_3D_Vector2> texCoordList;
	vector<FKCW_3D_Vector4> normalList;
	vector<FKCW_3D_Vector4> colorList;
	vector<FKCW_3D_IDTriangle> IDtriList;
	//generate positionList, texCoordList, normalList, colorList
	for(int i=0;i<=nStack;i++){
		float B=-90+i*dB;
		float y=r*sinf(B*PIDIV180);
		float cosB=cosf(B*PIDIV180);
		for (int j=0; j<=nSlice; j++) {
			float A=j*dA;
			float R=r*cosB;
			float x=R*cosf(A*PIDIV180);
			float z=R*sinf(A*PIDIV180);
			FKCW_3D_Vector4 position(x,y,z,1);
			float s=(float)j/nSlice+0.25f;
			float t=1-(float)i/nStack;
			FKCW_3D_Vector2 texCoord(s,t);
			FKCW_3D_Vector4 normal=normalize(FKCW_3D_Vector4(position.x(), position.y(), position.z(), 0));
			FKCW_3D_Vector4 color=southPoleColor*(1-(float)i/nStack)+northPoleColor*((float)i/nStack);
			positionList.push_back(position);
			texCoordList.push_back(texCoord);
			normalList.push_back(normal);
			colorList.push_back(color);
		}
	}
	//generate IDtriList
	for(int i=0;i<nStack;i++){
		for(int j=0;j<nSlice;j++){
			int vID_ld=(nSlice+1)*i+j;
			int vID_rd=vID_ld+1;
			int vID_ru=vID_rd+(nSlice+1);
			int vID_lu=vID_ru-1;
			FKCW_3D_IDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
			FKCW_3D_IDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
			IDtriList.push_back(IDtri0);
			IDtriList.push_back(IDtri1);
		}
	}
	FKCW_3D_SubMeshData*subMeshData=new FKCW_3D_SubMeshData();
	subMeshData->autorelease();
	subMeshData->init();
	subMeshData->initPositionList(positionList);
	subMeshData->initTexCoordList(texCoordList);
	subMeshData->initNormalList(normalList);
	subMeshData->initColorList(colorList);
	subMeshData->initIDtriList(IDtriList);
	FKCW_3D_SubMesh* subMesh=new FKCW_3D_SubMesh();
	subMesh->autorelease();
	subMesh->init();
	subMesh->setSubMeshData(subMeshData);
	FKCW_3D_Mesh* mesh=new FKCW_3D_Mesh();
	mesh->autorelease();
	mesh->init();
	mesh->addSubMesh(subMesh);
	return mesh;
}
예제 #26
0
	void loadObj(const string& fileName, const D3DXCOLOR& color, float scale, vector<Vertex>& vertices,
		unsigned int normalCount, unsigned int positionCount, unsigned int texCoordCount, unsigned int vertexCount)
	{
		vertices.reserve(vertexCount);

		ifstream inputFileStream(fileName.c_str());
		if (inputFileStream.fail())
		{
			throw exception();
		}

		char* rawSplit = new char[MAX_SPLIT_LENGTH];

        vector<string> lines = splitString(rawSplit, inputFileStream, '\n',
			normalCount + positionCount + texCoordCount + vertexCount / 3 + 50);

        vector<vector<string> > faces;
		faces.reserve(vertexCount / 3);
        vector<D3DXVECTOR3> normals;
		normals.reserve(normalCount);
        vector<D3DXVECTOR3> positions;
		positions.reserve(positionCount);
        vector<D3DXVECTOR2> texCoords;
		texCoords.reserve(texCoordCount);

        for (unsigned int lineIndex = 0; lineIndex < lines.size(); lineIndex++)
        {
			if (lines[lineIndex].empty())
			{
				continue;
			}

			istringstream inputLineStream(lines[lineIndex]);
			vector<string> splitLine = splitString(rawSplit, inputLineStream, ' ', 4);

            if (splitLine[0] == "v")
            {
				D3DXVECTOR3 position(
					(float) atof(splitLine[1].c_str()) * scale,
					(float) atof(splitLine[2].c_str()) * scale,
					(float) atof(splitLine[3].c_str()) * scale);
                positions.push_back(position);
            }
            else if (splitLine[0] == "vn")
            {
                D3DXVECTOR3 normal(
					(float) atof(splitLine[1].c_str()),
					(float) atof(splitLine[2].c_str()),
					(float) atof(splitLine[3].c_str()));
                normals.push_back(normal);
            }
            else if (splitLine[0] == "vt")
            {
                D3DXVECTOR2 texCoord(
					(float) atof(splitLine[1].c_str()),
					1.0f - (float) atof(splitLine[2].c_str()));
                texCoords.push_back(texCoord);
            }
            else if (splitLine[0] == "f")
            {
                faces.push_back(splitLine);
            }
        }

        // Read the faces from the file and populate the arrays.
        for (unsigned int faceIndex = 0; faceIndex < faces.size(); faceIndex++)
        {
			vector<string> face = faces[faceIndex];

            for (unsigned int vertexIndex = 1; vertexIndex < face.size() - 1; vertexIndex++)
            {
				istringstream inputFaceStream(face[vertexIndex]);
				vector<string> splitVertex = splitString(rawSplit, inputFaceStream, '/', 3);

				Vertex vertex;
				vertex.color = color;

				if (!normals.empty())
				{
					vertex.normal = normals[atoi(splitVertex[2].c_str()) - 1];
				}

                vertex.position = positions[atoi(splitVertex[0].c_str()) - 1];

				if (!texCoords.empty())
				{
					vertex.texCoord = texCoords[atoi(splitVertex[1].c_str()) - 1];
				}

				vertices.push_back(vertex);
            }

			// Create face normals if none were provided.
			if (normals.empty())
			{
				unsigned int vertexCount = vertices.size();

				D3DXVECTOR3 edge0 = vertices[vertexCount - 1].position - vertices[vertexCount - 2].position;
				D3DXVECTOR3 edge1 = vertices[vertexCount - 1].position - vertices[vertexCount - 3].position;
				D3DXVECTOR3 faceNormal;
				D3DXVec3Cross(&faceNormal, &edge0, &edge1);
				D3DXVec3Normalize(&faceNormal, &faceNormal);

				vertices[vertexCount - 1].normal = faceNormal;
				vertices[vertexCount - 2].normal = faceNormal;
				vertices[vertexCount - 3].normal = faceNormal;
			}
        }

		delete rawSplit;
	}
예제 #27
0
void GridMesh::GenerateGrid()
{
	uint numVerticies = rows * columns;
	vector<PositionTexCoordVertex> vertices(numVerticies);
	vector<vec3> points;

	auto width = columns * scale;
	auto height = rows * scale;

	auto halfWidth = width * 0.5f;
	auto halfHeight = height * 0.5f;

	vec3 originPosition(-halfWidth, 0, -halfHeight);

	for (uint row = 0; row < rows; row++)
	{
		for (uint column = 0; column < columns; column++)
		{
			auto index = row * columns + column;

			auto columnPosition = (float)column * scale;
			auto rowPosition = row * scale;

			vec3 position(columnPosition, 0, rowPosition);
			points.push_back(position);
			vertices[index].position = glm::vec4((originPosition + position), 1);

			glm::vec2 texCoord(row / (float)(rows), column / (float)columns);

			vertices[index].textureCoordinate = texCoord;
		}
	}
	//AddNoise(vertices);

	boundingSphere.Fit(points);

	auto numIndices = (rows - 1) * (columns - 1) * 6;


	vector<uint> indices(numIndices);

	uint index = 0;

	for (uint row = 0; row < rows - 1; row++)
	{
		for (uint column = 0; column < columns - 1; column++)
		{
			auto currentIndex = row * columns + column;
			auto nextRow = (row + 1) * columns + column;
			auto nextColumn = currentIndex + 1;
			auto nextRowNextColumn = nextRow + 1;

			assert(index + 6 <= numIndices);

			// First triangle
			indices[index++] = currentIndex;
			indices[index++] = nextRow;
			indices[index++] = nextRowNextColumn;

			// Second triangle
			indices[index++] = currentIndex;
			indices[index++] = nextRowNextColumn;
			indices[index++] = nextColumn;
		}
	}

	DynamicEnum texturePaths;
	texturePaths.Add(texturePath);

	BindVertexAndIndexData(&renderData, vertices, indices);
	BuildMaterialFromLoaderNode(&material, texturePaths);
}