Пример #1
0
Plane::Plane(float quadWidth, float quadHeight, unsigned int width, unsigned int height){
	//There's one more row of vertices than quads, same for columns
	unsigned int quadCount = width*height;
	unsigned int vertexCount = (width+1)*(height+1);

	// This is explained further down, but the formula for the amount of indices in the plane is
	// (quads per row * 2 + 1) * rows + 1
	// The last +1 is for the stitch leading into the plane altogether,
	// while the +1 for each row is for the stitch finalizing each strip (as well as starting the next one.)
	
	unsigned int indexCount = (2 * width + 1) * height + 1;

	Vertex* vertices = new Vertex[vertexCount];
	GLuint* indices = new GLuint[indexCount];

	GenerateVertices(vertices, quadWidth, quadHeight, width + 1, height + 1);
	GenerateUvCoordinates(vertices, 1.0f / quadWidth, 1.0f / quadHeight, width + 1, height + 1);
	GenerateIndices(indices, width, height);
	GenerateNormals(vertices, width + 1, height + 1);

	GenerateVao(vertices, indices, vertexCount, indexCount);

	delete[] vertices;
	delete[] indices;
}
Пример #2
0
void BaseMesh::CreateBox(float w, float h, float d, int refinement)
{
    Allocate(8, 12);

    MeshVertex Temp(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    for(i=0;i<8;i++)
    {
        Temp.Pos = Vec3f(CubeVData[i][0],CubeVData[i][1],CubeVData[i][2]);
        V[i] = Temp;        ///load the vertices
    }
    for(i=0;i<12;i++)
    {
        I[i*3+0] = CubeIData[i][0];
        I[i*3+1] = CubeIData[i][1];
        I[i*3+2] = CubeIData[i][2];    //load the triangles
    }

    for(i=0;i<refinement;i++)
    {
        TwoPatch();                //refine the requested number of times
    }

    Stretch(Vec3f(0.5f*w, 0.5f*h, 0.5f*d));    //stretch to the requested dimensions
    GenerateNormals();
}
Пример #3
0
void Cloth::Rebuffer()
{
	int nverts = 0;
	for(vector<SpringNode*>::iterator i = physicsCloth->nodes.begin(); i!=physicsCloth->nodes.end(); i++) {

		vertices[nverts] = (*i)->GetPosition();

		nverts++;

	}

	GenerateNormals();
	GenerateTangents();

	glBindVertexArray(arrayObject);
	glBindBuffer(GL_ARRAY_BUFFER, bufferObject[VERTEX_BUFFER]);
	glBufferSubData(GL_ARRAY_BUFFER,0 ,	numVertices*sizeof(Vector3), vertices);
	
	glBindBuffer(GL_ARRAY_BUFFER, bufferObject[NORMAL_BUFFER]);
	glBufferSubData(GL_ARRAY_BUFFER,0 ,	numVertices*sizeof(Vector3), normals);
	
	glBindBuffer(GL_ARRAY_BUFFER, bufferObject[TANGENT_BUFFER]);
	glBufferSubData(GL_ARRAY_BUFFER,0 ,	numVertices*sizeof(Vector3), tangents);


}
Пример #4
0
void CSplinedObject::Render(CMatrix& cCameraMatrix, CMatrix& cProjection)
{
    CObjectNode* pNode;
    CObjectNode* pEdge;

    if (!m_pRoot)
        return;

    glMatrixMode(GL_MODELVIEW);
    glMultMatrixf(cCameraMatrix.m_.aMatrix);
    glMultMatrixf(m_cMatrix.m_.aMatrix);

    if (m_bGenerateNormals)
    {
        CMatrix cModelView;
        glGetFloatv(GL_MODELVIEW_MATRIX, (float*)&cModelView.m_.aMatrix);
        GenerateNormals(cModelView);
    }

    glEnable(GL_TEXTURE_2D);

    pEdge = m_pRoot;

    do {
        pNode = pEdge;
        do
        {
            pNode->RenderPatch(m_nSeedU, m_nSeedV, m_aMultiTex, m_nMultiTex);
            pNode = pNode->m_pRight;
        } while (pNode->m_pRight && pNode != pEdge);

        pEdge = pEdge->m_pDown;
    } while (pEdge->m_pDown);
}
Пример #5
0
void Target_Octahedron::Sizer(void)
{
	dx = manager->CashedDx();

	minJx = minJy = minJz =  ihuge_;
	maxJx = maxJy = maxJz = -ihuge_;

	GenerateVertices();
	GenerateNormals();

	int nlong = (int)shpar[0];
	real nlongHalf = nlong / (real)2.;
//
	for(int jx=0; jx<=nlong; ++jx)
	{
		real x = (real)jx - nlongHalf;
		for(int jy=0; jy<=nlong; ++jy)
		{
			real y = (real)jy - nlongHalf;
			for(int jz=0; jz<=nlong; ++jz)
			{
				real z = (real)jz - nlongHalf;
				if (Check(x, y, z))
				{
					InternalMinMax(jx, jy, jz);
				}
			}
		}
	}

	AllocateArrays(maxJx - minJx + 1, maxJy - minJy + 1, maxJz - minJz + 1);
}
Пример #6
0
void Target_Dodecahedron::Sizer(void)
{
	dx = manager->CashedDx();

	minJx = minJy = minJz =  ihuge_;
	maxJx = maxJy = maxJz = -ihuge_;

	GenerateVertices();
	GenerateNormals();

	int na  = (int)vertices[5].data[0];
	int nb  = (int)vertices[6].data[1];
	int nzz = (int)vertices[0].data[2];

	for(int ix=-na; ix<=na; ++ix)
	{
		real x = (real)ix;
		for(int iy=-nb; iy<=nb; ++iy)
		{
			real y = (real)iy;
			for(int iz=-nzz; iz<=nzz; ++iz)
			{
				real z = (real)iz;
				bool bOk = Check(x, y, z);
				if (bOk)
				{
					InternalMinMax(ix, iy, iz);
				}
			}
		}
	}
//
	AllocateArrays(maxJx - minJx + 1, maxJy - minJy + 1, maxJz - minJz + 1);
}
Пример #7
0
void BaseMesh::ReCreateCylinder(Vec3f (*PositionFunction) (float), float Start, float End, float radius, UINT slices, UINT stacks)
{
    MeshVertex *V = Vertices();

    Matrix4 Face, Translate;
    Vec3f Tangent;
    float DeltaT = 0.0001f,Time,Theta;
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    Vec3f CurPos;

    for(UINT i = 0; i <= stacks; i++)
    {
        Time = float(Math::LinearMap(0.0f,float(stacks),Start,End,float(i)));        //get the approriate value between Start and End
        CurPos = PositionFunction(Time);        //get the current position along the curve
        
        if(Time + DeltaT <= End) Tangent = PositionFunction(Time + DeltaT) - CurPos;    //approximate the derivative (tangent vector)
        else Tangent = CurPos - PositionFunction(Time - DeltaT);
        Face = Matrix4::Face(Vec3f(0.0f, 0.0f, 1.0f), Tangent);    //face Matrix4 causes the local cylinder ring to face the right direction
        Translate = Matrix4::Translation(CurPos);                //the local cylinder ring should be centered on CurPos
        Face = Face * Translate;

        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Theta = float(i2) * PI2_Slices;
            V[i*slices+i2].Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), 0.0f);    //construct the basic circle
            V[i*slices+i2].Pos = Face.TransformPoint(V[i*slices+i2].Pos);                //transform the circle to its approrpriate using the Matrix4
        }
    }

    GenerateNormals();
}
Пример #8
0
void BaseMesh::ReCreateCylinder(float radius, const Vec3f &pt1, const Vec3f &pt2, UINT slices, UINT stacks)
{
    //a merge of the CreateCylinder(radius, height, slices, stacks) and CreateCylinder(radius, pt1, pt2, slices, stacks)
    Vec3f Diff = pt2 - pt1;
    float height = Diff.Length();
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    float Theta;

    int vc = 0, ic = 0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(UINT i = 0; i <= stacks; i++)
    {
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Theta = float(i2) * PI2_Slices;
            MVtx.Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), height * (float(i) / stacks - 0.5f));
            V[vc++] = MVtx;
        }
    }

    Matrix4 T1 = Matrix4::Translation(Vec3f(0.0f,0.0f,height / 2.0f));
    Matrix4 Face = Matrix4::Face(Vec3f(0.0f,0.0f,1.0f),pt2 - pt1);
    Matrix4 T2 = Matrix4::Translation(pt1);

    ApplyMatrix(T1 * Face * T2);
    GenerateNormals();
}
Пример #9
0
void D3D9Mesh::CreateText(const char *string, char *FontName, int FontHeight,
                float deviation, float depth, bool bold, bool italic)
{
    //just call the DirectX function to create the text
    FreeMemory();
    LPD3DXMESH TextMesh;
    
    HDC hdc = CreateCompatibleDC( NULL );
    HFONT hFont;
    HFONT hFontOld;
    
    INT nHeight = -MulDiv( FontHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72 );
    hFont = CreateFont(nHeight, 0, 0, 0, bold ? FW_BOLD : FW_NORMAL, italic, FALSE, FALSE, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, FontName);
    hFontOld = (HFONT)SelectObject(hdc, hFont); 

    if(FAILED(D3DXCreateText(GetD3DDevice(), hdc, string, deviation, depth, &TextMesh, NULL, NULL))) _asm int 3;

    SelectObject(hdc, hFontOld);
    DeleteObject( hFont );
    DeleteDC( hdc );

    TextMesh->CloneMeshFVF(D3DMeshOptions, D3DMeshFVF, GetD3DDevice(), &_Mesh);
    TextMesh->Release();
    SetColor(RGBColor::White);
    GenerateNormals();
}
Пример #10
0
Model ModelLoader::Load(const string &aFileName,
                               bool aNormalizeMesh /*= false*/)
{
    ResetLoader();
    
    cout << "Loading mesh " << aFileName << " ... ";
    
    FILE* pFile = fopen(aFileName.c_str(),"rb");
    
    while(!feof(pFile))
    {
        DispatchRead(pFile);
    }
    
    if(mNormals.size() == 1)
    {
        GenerateNormals();
    }

    if(aNormalizeMesh)
    {
        NormalizeMesh();
    }

	
    unsigned int GLId = FillPrimitive();
    
    fclose(pFile);
    cout << "DONE." << endl;

    Model RetVal(mVertices, mCombinedVertices,GLId);
    
    return RetVal;
}
Пример #11
0
	void ObjParser::IdentifieLoadedFormat(DWORD& FVF, D3DVERTEXELEMENT9* &pMeshVDeclaration, int &code)
	{
		if( Vertexs.size() != 0 && Normals.size() != 0 && Textures.size() != 0 )//All
		{
			pMeshVDeclaration = VertexTextureNormal::VertexElement;
			FVF = D3DFVF_XYZ | D3DFVF_TEX0 | D3DFVF_NORMAL;
			code = 4;
		}
		else if( Vertexs.size() != 0 && Textures.size() != 0 )//just Texture
		{
			if( m_ForceNormals )
			{
				GenerateNormals();
				pMeshVDeclaration = VertexTextureNormal::VertexElement;
				FVF = D3DFVF_XYZ | D3DFVF_TEX0 | D3DFVF_NORMAL;
				code = 4;
			}else
			{
				pMeshVDeclaration = VertexTexture::VertexElement;
				FVF = D3DFVF_XYZ | D3DFVF_TEX0;
				code = 3;
			}
		}
		else if( Vertexs.size() != 0 && Normals.size() != 0 )//just Normal
		{
			pMeshVDeclaration = VertexNormal::VertexElement;
			FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
			code = 2;
		}
		else
		{
			if( m_ForceNormals )
			{
				GenerateNormals();
				pMeshVDeclaration = VertexNormal::VertexElement;
				FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
				code = 2;
			}else
			{
				pMeshVDeclaration = Vertex::VertexElement;
				FVF = D3DFVF_XYZ;
				code = 1;
			}
		}

		return;
	}
Пример #12
0
void BaseMesh::CreateTorus(float MainRadius, float SmallRadius, UINT slices, UINT stacks)
{
    //much like all the others shape functions...create a torus by taking a cylinder and wrapping
    //it around a point in space, then connect the two ends.

    Allocate(slices * stacks,2 * stacks * slices);

    float PI2_Stacks = 2.0f * Math::PIf / float(stacks);
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    float Theta,SinT,CosT,Phi,SinP;

    UINT vc = 0, ic = 0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(UINT i = 0; i < stacks; i++)
    {
        Theta = float(i) * PI2_Stacks;
        SinT = sinf(Theta);
        CosT = cosf(Theta);
        Vec3f MainTranslation(CosT*MainRadius,SinT*MainRadius,0.0f);
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Phi = float(i2) * PI2_Slices;
            SinP = sinf(Phi);
            MVtx.Pos = Vec3f(SmallRadius * CosT * SinP, SmallRadius * SinT * SinP, SmallRadius * cosf(Phi)) + MainTranslation;
            V[vc++] = MVtx;
        }
    }

    UINT i2p1,ip1;
    for(UINT i = 0; i < stacks; i++)
    {
        ip1 = i + 1;
        if(ip1 == stacks)
        {
            ip1 = 0;
        }
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            i2p1 = i2 + 1;
            if(i2p1 == slices) i2p1 = 0;
            
            I[ic++] = ip1 * slices + i2;
            I[ic++] = i * slices + i2;
            I[ic++] = i * slices + i2p1;

            
            I[ic++] = ip1 * slices + i2;
            I[ic++] = i * slices + i2p1;
            I[ic++] = ip1 * slices + i2p1;
        }
    }

    GenerateNormals();
}
Пример #13
0
void BaseMesh::RotateFaces()
{
    DWORD *_Indices = Indices();
    UINT _FaceCount = FaceCount();
    for(UINT FaceIndex = 0; FaceIndex < _FaceCount; FaceIndex++)
    {
        Utility::Swap(_Indices[FaceIndex * 3 + 0], _Indices[FaceIndex * 3 + 1]);
    }
    GenerateNormals();
}
Пример #14
0
Cloth::Cloth(PhysicsCloth* pc){

	physicsCloth = pc;
	numVertices = pc->height * pc->width;
	numIndices =  (pc->height-1 )* (pc->width-1 )* 6;

	vertices	  = new Vector3[numVertices];
	textureCoords = new Vector2[numVertices];
	indices		  = new GLuint[numIndices];
	
	for(int i = 0; i < pc->width; i++)
	{
		for(int j = 0;  j < pc->height; j++)
		{
			int index = (i*pc->width) + j;
			textureCoords[index] = Vector2((float)i/(float)pc->width, (float)j/(float)pc->height);
			//textureCoords[index] = Vector2(rand() % 100 / 100.0f,rand() % 100 / 100.0f);
		}
	}

	int nverts = 0;
	for(vector<SpringNode*>::iterator i = pc->nodes.begin(); i!=pc->nodes.end(); i++) {

		vertices[nverts] = (*i)->GetPosition();

		nverts++;

	}
	
	numIndices = 0;

	for(int x = 0; x < pc->width-1; ++x)	{
		for(int z = 0; z < pc->height-1; ++z)	{
			int a = (x		* (pc->width)) + z;
			int b = ((x+1)  * (pc->width)) + z;
			int c = ((x+1)  * (pc->width)) + (z+1);
			int d = (x		* (pc->width)) + (z+1);
		
			indices[numIndices++] = c;
			indices[numIndices++] = b;
			indices[numIndices++] = a;

			indices[numIndices++] = a;
			indices[numIndices++] = d;
			indices[numIndices++] = c;

		}
	}
	GenerateNormals();
	GenerateTangents();
	GenerateColours();
	BufferData();

}
// -------------------------------------------------------------------------- //
void Class_SurfTri::Scale(
    double           sx,
    double           sy,
    double           sz
) {

// ========================================================================== //
// void Class_SurfTri::Scale(                                                 //
//     double           sx,                                                   //
//     double           sy,                                                   //
//     double           sz)                                                   //
//                                                                            //
// Scale tasselation along x, y, z axis by factor sx, sy and sz               //
// respectively.                                                              //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - sx     : double, scaling factor along x direction                        //
// - sy     : double, scaling factor along y direction                        //
// - sz     : double, scaling factor along z direction                        //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - none                                                                     //
// ========================================================================== //

// ========================================================================== //
// VARIABLES DECLARATION                                                      //
// ========================================================================== //

// Local variables
// none

// Counters
    int      i;

// ========================================================================== //
// SCALE TASSELATION                                                          //
// ========================================================================== //

// Vertex ------------------------------------------------------------------- //
    for (i = 0; i < nVertex; i++) {
        Vertex[i][0] = sx*Vertex[i][0];
        Vertex[i][1] = sy*Vertex[i][1];
        Vertex[i][2] = sz*Vertex[i][2];
    } //next i

// Normals ------------------------------------------------------------------ //
    if ((Normal.size() > 0) && (Normal.size() >= nSimplex)) {
        GenerateNormals();
    }

    return;
};
Пример #16
0
void BaseMesh::CreateCylinder(float radius, const Vec3f &pt1, const Vec3f &pt2, UINT slices, UINT stacks)
{
    float height = (pt2 - pt1).Length();
    CreateCylinder(radius, height, slices, stacks);    //create a basic cylinder of the appropriate height

    Matrix4 Face = Matrix4::Face(Vec3f::eZ, pt2 - pt1);                    //make it face the direction pt2 - pt1 instead of eZ
    Matrix4 T2 = Matrix4::Translation(pt1);                                //translate it so it goes from pt1 -> pt2

    ApplyMatrix(Face * T2);
    GenerateNormals();
}
Пример #17
0
void BaseMesh::CreateClosedCylinder(float radius, const Vec3f &pt1, const Vec3f &pt2, UINT slices, UINT stacks)
{
    float height = (pt2 - pt1).Length();
    CreateClosedCylinder(radius, height, slices, stacks);    //create a basic cylinder of the appropriate height

    Matrix4 T1 = Matrix4::Translation(Vec3f(0.0f,0.0f,height / 2.0f));    //translate so it goes from Origin to eZ*height
    Matrix4 Face = Matrix4::Face(Vec3f::eZ, pt2 - pt1);                        //make it face the direction pt2 - pt1 instead of eZ
    Matrix4 T2 = Matrix4::Translation(pt1);                            //translate it so it goes from pt1 -> pt2 as requested

    ApplyMatrix(T1 * Face * T2);    //apply the constructed Matrix4
    GenerateNormals();
}
Пример #18
0
Sphere::Sphere(glm::vec3 pos, float radius, unsigned int rings, unsigned int sectors)
{
    m_pos = m_centerPos = pos;
    m_radius = radius;
    m_rings = rings;
    m_sectors = sectors;

    CreateBuffers();
    GenerateVertices();
    GenerateIndexes();
    GenerateNormals();
}
Пример #19
0
void D3D9Mesh::CreateTeapot(float radius)
{
    //just call the DirectX function to create the teapot
    FreeMemory();
    LPD3DXMESH teapot;
    D3DXCreateTeapot(GetD3DDevice(), &teapot, NULL);
    teapot->CloneMeshFVF(D3DMeshOptions, D3DMeshFVF, GetD3DDevice(), &_Mesh);
    teapot->Release();
    Stretch(radius);
    SetColor(RGBColor::White);
    GenerateNormals();
}
Пример #20
0
/*
=================
idSurface_Patch::SubdivideExplicit
=================
*/
void idSurface_Patch::SubdivideExplicit( int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear ) {
	int i, j, k, l;
	idDrawVert sample[3][3];
	int outWidth = ((width - 1) / 2 * horzSubdivisions) + 1;
	int outHeight = ((height - 1) / 2 * vertSubdivisions) + 1;
	idDrawVert *dv = new idDrawVert[ outWidth * outHeight ];

	// generate normals for the control mesh
	if ( genNormals ) {
		GenerateNormals();
	}

	int baseCol = 0;
	for ( i = 0; i + 2 < width; i += 2 ) {
		int baseRow = 0;
		for ( j = 0; j + 2 < height; j += 2 ) {
			for ( k = 0; k < 3; k++ ) {
				for ( l = 0; l < 3; l++ ) {
					sample[k][l] = verts[ ((j + l) * width) + i + k ];
				}
			}
			SampleSinglePatch( sample, baseCol, baseRow, outWidth, horzSubdivisions, vertSubdivisions, dv );
			baseRow += vertSubdivisions;
		}
		baseCol += horzSubdivisions;
	}
	verts.SetNum( outWidth * outHeight );
	for ( i = 0; i < outWidth * outHeight; i++ ) {
		verts[i] = dv[i];
	}

	delete[] dv;

	width = maxWidth = outWidth;
	height = maxHeight = outHeight;
	expanded = false;

	if ( removeLinear ) {
		Expand();
		RemoveLinearColumnsRows();
		Collapse();
	}

	// normalize all the lerped normals
	if ( genNormals ) {
		for ( i = 0; i < width * height; i++ ) {
			verts[i].normal.Normalize();
		}
	}

	GenerateIndexes();
}
Пример #21
0
void BaseMesh::CreateCylinder(float radius, float height, UINT slices, UINT stacks)
{
    //this code is almost identical to CreateSphere(radius, slices, stacks) except there is no TopVertex/Bottom vertex,
    //and there is only one angle (and instead there is a height.)
    Allocate(slices * (stacks + 1), 2 * stacks * slices);
    
    float PI2_Slices = 2.0f * Math::PIf / float(slices);
    float Theta;

    int vc=0, ic=0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    for(UINT i = 0; i <= stacks; i++)
    {
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Theta = float(i2) * PI2_Slices;
            MVtx.Pos = Vec3f(radius * cosf(Theta), radius * sinf(Theta), height * float(i) / float(stacks));
            MVtx.TexCoord.x = i / float(stacks);
            MVtx.TexCoord.y = i2 / float(slices - 1);
            V[vc++] = MVtx;
        }
    }

    for(UINT i=0;i < stacks;i++)
    {
        for(UINT i2=0;i2 < slices;i2++)
        {
            int i2p1 = i2 + 1;
            if(i2p1 == slices) i2p1 = 0;
            
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = i * slices + i2;
            I[ic++] = i * slices + i2p1;

            
            I[ic++] = (i+1) * slices + i2;
            I[ic++] = i * slices + i2p1;
            I[ic++] = (i+1) * slices + i2p1;
        }
    }

    GenerateNormals();
}
Пример #22
0
void BaseMesh::CreatePlane(float size, UINT slicesX, UINT slicesY)
{
    Allocate(slicesX * slicesY, (slicesX - 1) * (slicesY - 1) * 2);
    
    UINT vc = 0, ic = 0;
    MeshVertex *V = Vertices();
    DWORD *I = Indices();
    MeshVertex MVtx(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    float ConversionX = (size / (slicesX - 1));
    float ConversionY = (size / (slicesY - 1));
    for(UINT i = 0; i < slicesX; i++)
    {
        for(UINT i2 = 0; i2 < slicesY; i2++)
        {
            MVtx.Pos.x = ConversionX * float(i) - size / 2.0f;
            MVtx.Pos.y = ConversionY * float(i2) - size / 2.0f;
            MVtx.TexCoord.x = i / float(slicesX - 1);
            MVtx.TexCoord.y = i2 / float(slicesY - 1);
            V[vc++] = MVtx;
        }
    }

    for(UINT i = 0; i < slicesY - 1; i++)
    {
        for(UINT i2 = 0; i2 < slicesX - 1; i2++)
        {
            I[ic++] = slicesY*i2+i;
            I[ic++] = slicesY*i2+(i+1);
            I[ic++] = slicesY*(i2+1)+i;
            I[ic++] = slicesY*i2+(i+1);
            I[ic++] = slicesY*(i2+1)+(i+1);
            I[ic++] = slicesY*(i2+1)+i;
        }
    }

    GenerateNormals();
}
Пример #23
0
void BaseMesh::CreateSphere(float radius, int refinement)
{
    //allocate space for the icosahedron
    Allocate(12, 20);

    MeshVertex Temp(Vec3f::Origin, Vec3f::Origin, RGBColor::White, Vec2f::Origin);

    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    for(i=0;i<12;i++)
    {
        Temp.Pos = Vec3f(IcosahedronVData[i][0],IcosahedronVData[i][1],IcosahedronVData[i][2]);
        V[i] = Temp;                        //load the icosahedron vertices
    }
    for(i=0;i<20;i++)
    {
        I[i*3+0] = IcosahedronIData[i][1];
        I[i*3+1] = IcosahedronIData[i][0];
        I[i*3+2] = IcosahedronIData[i][2];    //load the icosahedron indices
    }

    for(i=0;i<refinement;i++)
        TwoPatch();                //refine the specified number of times

    vc=VertexCount();
    V = Vertices();

    for(i=0;i<vc;i++)
    {
        V[i].Pos = Vec3f::Normalize(V[i].Pos);
        V[i].Pos *= radius;        //project all the points to lie on a sphere of the specified radius
    }

    GenerateNormals();            //generate normals
    SetColor(RGBColor::White);
}
Пример #24
0
BabylonMesh::BabylonMesh(BabylonNode* node) :
	BabylonAbstractMesh(node),
	_isEnabled(true),
	_isVisible(true),
	_billboardMode(0),
	_visibility(1),
	_skeletonId(-1),
	_pickable(true),
	_hasVertexAlpha(false),
	_checkCollision(false),
	_receiveShadows(false),
	_infiniteDistance(false),
	_autoAnimate(false),
	_autoAnimateFrom(0),
	_autoAnimateTo(0),
	_autoAnimateLoop(false),
	_showBoundingBox(false),
	_showSubMeshesBoundingBox(false),
	_applyFog(false),
	_alphaIndex(0)
{

	pivotMatrix.SetIdentity();
	auto fbxNode = node->fbxNode();
	
	std::string ansiName = fbxNode->GetName();
	name(std::wstring(ansiName.begin(), ansiName.end()));
	id(getNodeId(fbxNode));
	auto parent = fbxNode->GetParent();
	if (parent) {
		parentId(getNodeId(parent));
	}
	pivotMatrix = ConvertToBabylonCoordinateSystem( GetGeometryTransformation(fbxNode));

	auto animStack = fbxNode->GetScene()->GetSrcObject<FbxAnimStack>(0);
	FbxString animStackName = animStack->GetName();
	FbxTakeInfo* takeInfo = fbxNode->GetScene()->GetTakeInfo(animStackName);
	auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
	auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(animTimeMode);
	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode);
	auto animLengthInFrame = endFrame - startFrame + 1;
	_visibility = static_cast<float>(node->fbxNode()->Visibility.Get());
	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotationQuaternion", L"rotationQuaternion", true, 0, static_cast<int>(animLengthInFrame), true);
	auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"scaling", L"scaling", true, 0, static_cast<int>(animLengthInFrame), true);
	auto visibilityAnim = std::make_shared<BabylonAnimation<float>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"visibility", L"visibility", true, 0, static_cast<int>(animLengthInFrame), true);
	auto mesh = fbxNode->GetMesh();
	_isVisible = fbxNode->Show.Get();
	
	auto rotCurveNode = fbxNode->LclRotation.GetCurveNode();
	auto translateCurveNode = fbxNode->LclTranslation.GetCurveNode();
	auto scalingCurveNode = fbxNode->LclScaling.GetCurveNode();
	auto visibilityCurveNode = fbxNode->Visibility.GetCurveNode();
	if (rotCurveNode || translateCurveNode || scalingCurveNode) {
		for (auto ix = 0; ix < animLengthInFrame; ix++) {
			FbxTime currTime;
			currTime.SetFrame(startFrame + ix, animTimeMode);

			babylon_animation_key<babylon_vector3> poskey;
			babylon_animation_key<babylon_vector4> rotkey;
			babylon_animation_key<babylon_vector3> scalekey;
			poskey.frame = ix;
			rotkey.frame = ix;
			scalekey.frame = ix;
			auto currTransform = node->GetLocal(currTime);
			poskey.values = currTransform.translation();
			rotkey.values = currTransform.rotationQuaternion();
			scalekey.values = currTransform.scaling();
			posAnim->appendKey(poskey);
			rotAnim->appendKey(rotkey);
			scaleAnim->appendKey(scalekey);


		}
	}
	if (visibilityCurveNode) {
		for (auto ix = 0; ix < animLengthInFrame; ix++) {
			FbxTime currTime;
			currTime.SetFrame(startFrame + ix, animTimeMode);

			babylon_animation_key<float> visibilityKey;

			visibilityKey.frame = ix;

			visibilityKey.values = static_cast<float>(node->fbxNode()->Visibility.EvaluateValue(currTime));

			visibilityAnim->appendKey(visibilityKey);


		}
	}
	
	if (!posAnim->isConstant()){
		animations.push_back(posAnim);
	}
	if (!rotAnim->isConstant()){
		animations.push_back(rotAnim);
	}
	if (!scaleAnim->isConstant()){
		animations.push_back(scaleAnim);
	}
	if (!visibilityAnim->isConstant()) {
		animations.push_back(visibilityAnim);
	}
	if (!mesh) {
		return;
	}
	if (mesh->GetPolygonCount() == 0){
		return;
	}

	_receiveShadows =  mesh->ReceiveShadow.Get();
	FbxGeometryConverter conv(mesh->GetFbxManager());
	conv.ComputePolygonSmoothingFromEdgeSmoothing(mesh);
	if (!mesh->IsTriangleMesh()) {
		mesh = (FbxMesh*) conv.Triangulate(mesh, true);
	}


	mesh->RemoveBadPolygons();
	mesh->GenerateNormals();

	FbxStringList uvSetNameList;
	mesh->GetUVSetNames(uvSetNameList);
	std::vector<std::string> uniqueUVSets;

	int uvCount = uvSetNameList.GetCount();
	for (int i = 0; i < uvCount; ++i) {
		std::string value = uvSetNameList.GetStringAt(i);
		if (std::find(uniqueUVSets.begin(), uniqueUVSets.end(), value) == uniqueUVSets.end()) {
			uniqueUVSets.push_back(value);
		}
	}
	uvsets = uniqueUVSets;
	bool hasUv = uniqueUVSets.size() > 0;
	bool hasUv2 = uniqueUVSets.size() > 1;
	bool hasUv3 = uniqueUVSets.size() > 2;
	bool hasUv4 = uniqueUVSets.size() > 3;
	bool hasUv5 = uniqueUVSets.size() > 4;
	bool hasUv6 = uniqueUVSets.size() > 5;
	std::string uvSetName;
	std::string uv2SetName;
	std::string uv3SetName;
	std::string uv4SetName;
	std::string uv5SetName;
	std::string uv6SetName;
	if (hasUv) {
		uvSetName = uniqueUVSets[0];
	}
	if (hasUv2) {
		uv2SetName = uniqueUVSets[1];
	}
	if (hasUv3) {
		uv3SetName = uniqueUVSets[2];
	}
	if (hasUv4) {
		uv4SetName = uniqueUVSets[3];
	}
	if (hasUv5) {
		uv5SetName = uniqueUVSets[4];
	}
	if (hasUv6) {
		uv6SetName = uniqueUVSets[5];
	}
	auto colors = mesh->GetElementVertexColor();
	FbxLayerElement::EMappingMode colorMappingMode;
	FbxLayerElement::EReferenceMode colorReferenceMode;
	if (colors) {
		colorMappingMode = colors->GetMappingMode();
		colorReferenceMode = colors->GetReferenceMode();
	}
	auto normals = mesh->GetElementNormal();
	FbxGeometryElementUV* uvs = nullptr;
	FbxGeometryElementUV* uvs2 = nullptr;
	FbxGeometryElementUV* uvs3 = nullptr;
	FbxGeometryElementUV* uvs4 = nullptr;
	FbxGeometryElementUV* uvs5 = nullptr;
	FbxGeometryElementUV* uvs6 = nullptr;
	FbxLayerElement::EMappingMode uvsMappingMode;
	FbxLayerElement::EReferenceMode uvsReferenceMode;
	FbxLayerElement::EMappingMode uvs2MappingMode;
	FbxLayerElement::EReferenceMode uvs2ReferenceMode;
	FbxLayerElement::EMappingMode uvs3MappingMode;
	FbxLayerElement::EReferenceMode uvs3ReferenceMode;
	FbxLayerElement::EMappingMode uvs4MappingMode;
	FbxLayerElement::EReferenceMode uvs4ReferenceMode;
	FbxLayerElement::EMappingMode uvs5MappingMode;
	FbxLayerElement::EReferenceMode uvs5ReferenceMode;
	FbxLayerElement::EMappingMode uvs6MappingMode;
	FbxLayerElement::EReferenceMode uvs6ReferenceMode;
	if (hasUv) {
		uvs = mesh->GetElementUV(uvSetName.c_str());
		uvsMappingMode = uvs->GetMappingMode();
		uvsReferenceMode = uvs->GetReferenceMode();
	}
	if (hasUv2) {
		uvs2 = mesh->GetElementUV(uv2SetName.c_str());
		uvs2MappingMode = uvs2->GetMappingMode();
		uvs2ReferenceMode = uvs2->GetReferenceMode();
	}
	if (hasUv3) {
		uvs3 = mesh->GetElementUV(uv3SetName.c_str());
		uvs3MappingMode = uvs3->GetMappingMode();
		uvs3ReferenceMode = uvs3->GetReferenceMode();
	}
	if (hasUv4) {
		uvs4 = mesh->GetElementUV(uv4SetName.c_str());
		uvs4MappingMode = uvs4->GetMappingMode();
		uvs4ReferenceMode = uvs4->GetReferenceMode();
	}
	if (hasUv5) {
		uvs5 = mesh->GetElementUV(uv5SetName.c_str());
		uvs5MappingMode = uvs5->GetMappingMode();
		uvs5ReferenceMode = uvs5->GetReferenceMode();
	}
	if (hasUv6) {
		uvs6 = mesh->GetElementUV(uv6SetName.c_str());
		uvs6MappingMode = uvs6->GetMappingMode();
		uvs6ReferenceMode = uvs6->GetReferenceMode();
	}

	auto normalMappingMode = normals->GetMappingMode();
	auto normalReferenceMode = normals->GetReferenceMode();
	std::vector<SubmeshData> submeshes;

	auto materialCount = node->fbxNode()->GetMaterialCount();
	if (materialCount == 0) {
		materialCount = 1;
	}
	submeshes.resize(materialCount);
	auto baseLayer = mesh->GetLayer(0);
	auto materials = baseLayer->GetMaterials();
	FbxLayerElement::EMappingMode materialMappingMode = materials ?
		materials->GetMappingMode() : FbxLayerElement::eByPolygon;

	// extract deformers
	SkinInfo skinInfo(fbxNode);
	if (skinInfo.hasSkin()){
		associatedSkeleton = std::make_shared<BabylonSkeleton>();
		skinInfo.buildBabylonSkeleton(*associatedSkeleton);
	}

	auto triangleCount = mesh->GetPolygonCount();
	for (int triangleIndex = 0; triangleIndex < triangleCount; ++triangleIndex) {

		int materialIndex = 0;
		if (materialCount > 0 && materials) {
			switch (materialMappingMode) {
			case FbxLayerElement::eAllSame:
				materialIndex = materials->GetIndexArray().GetAt(0);
				break;
			case FbxLayerElement::eByPolygon:
				materialIndex = materials->GetIndexArray().GetAt(triangleIndex);
			}
		}

		auto& submesh = submeshes[materialIndex];
		triangle t;
		for (int cornerIndex = 0; cornerIndex < 3; ++cornerIndex) {
			auto controlPointIndex = mesh->GetPolygonVertex(triangleIndex, cornerIndex);
			auto vertexIndex = triangleIndex * 3 + cornerIndex;
			auto position = mesh->GetControlPoints()[controlPointIndex];
			position[2] = -position[2];

			BabylonVertex v;
			v.position = position;
			if (normals) {
				int normalMapIndex = (normalMappingMode == FbxLayerElement::eByControlPoint) ?
				controlPointIndex : vertexIndex;
				int normalValueIndex = (normalReferenceMode == FbxLayerElement::eDirect) ?
				normalMapIndex : normals->GetIndexArray().GetAt(normalMapIndex);
				v.normal = normals->GetDirectArray().GetAt(normalValueIndex);
				v.normal.z = -v.normal.z;
			}
			if (colors) {
				int mappingIndex = (colorMappingMode == FbxLayerElement::eByControlPoint) ?
				controlPointIndex : vertexIndex;
				int valueIndex = (colorReferenceMode == FbxLayerElement::eDirect) ?
				mappingIndex : colors->GetIndexArray().GetAt(mappingIndex);
				v.color = colors->GetDirectArray().GetAt(valueIndex);
			}
			if (uvs) {
				int mappingIndex = (uvsMappingMode == FbxLayerElement::eByControlPoint) ?
				controlPointIndex : vertexIndex;
				int valueIndex = (uvsReferenceMode == FbxLayerElement::eDirect) ?
				mappingIndex : uvs->GetIndexArray().GetAt(mappingIndex);
				v.uv = uvs->GetDirectArray().GetAt(valueIndex);
				//v.uv.y = 1 - v.uv.y;
			}

			if (uvs2) {
				int mappingIndex = (uvs2MappingMode == FbxLayerElement::eByControlPoint) ?
					controlPointIndex : vertexIndex;
				int valueIndex = (uvs2ReferenceMode == FbxLayerElement::eDirect) ?
					mappingIndex : uvs2->GetIndexArray().GetAt(mappingIndex);
				v.uv2 = uvs2->GetDirectArray().GetAt(valueIndex);
			}
			if (uvs3) {
				int mappingIndex = (uvs3MappingMode == FbxLayerElement::eByControlPoint) ?
					controlPointIndex : vertexIndex;
				int valueIndex = (uvs3ReferenceMode == FbxLayerElement::eDirect) ?
					mappingIndex : uvs3->GetIndexArray().GetAt(mappingIndex);
				v.uv3 = uvs3->GetDirectArray().GetAt(valueIndex);
			}
			if (uvs4) {
				int mappingIndex = (uvs4MappingMode == FbxLayerElement::eByControlPoint) ?
					controlPointIndex : vertexIndex;
				int valueIndex = (uvs4ReferenceMode == FbxLayerElement::eDirect) ?
					mappingIndex : uvs4->GetIndexArray().GetAt(mappingIndex);
				v.uv4 = uvs4->GetDirectArray().GetAt(valueIndex);
			}
			if (uvs5) {
				int mappingIndex = (uvs5MappingMode == FbxLayerElement::eByControlPoint) ?
					controlPointIndex : vertexIndex;
				int valueIndex = (uvs5ReferenceMode == FbxLayerElement::eDirect) ?
					mappingIndex : uvs5->GetIndexArray().GetAt(mappingIndex);
				v.uv5 = uvs5->GetDirectArray().GetAt(valueIndex);
			}
			if (uvs6) {
				int mappingIndex = (uvs6MappingMode == FbxLayerElement::eByControlPoint) ?
					controlPointIndex : vertexIndex;
				int valueIndex = (uvs6ReferenceMode == FbxLayerElement::eDirect) ?
					mappingIndex : uvs6->GetIndexArray().GetAt(mappingIndex);
				v.uv6 = uvs6->GetDirectArray().GetAt(valueIndex);
			}
			if (skinInfo.hasSkin()){
				auto& skinData = skinInfo.controlPointBoneIndicesAndWeights(controlPointIndex);
				for (auto boneix = 0; boneix < skinData.size()&&boneix<4; ++boneix){
					v.boneIndices[boneix] = skinData[boneix].index;
					v.boneWeights[boneix] = static_cast<float>(skinData[boneix].weight);
				}
				for (auto boneix = skinData.size(); boneix < 4; ++boneix){

					v.boneIndices[boneix] = skinInfo.bonesCount();
					v.boneWeights[boneix] = 0;
				}
			}
			auto foundVertex = submesh.knownVertices.find(v);
			if (foundVertex != submesh.knownVertices.end()) {
				//submesh.indices.push_back(foundVertex->second);
				t.indices[cornerIndex] = foundVertex->second;
			}
			else {
				auto index = static_cast<int>(submesh.vertices.size());
				submesh.vertices.push_back(v);
				//submesh.indices.push_back(index);
				submesh.knownVertices[v] = index;
				t.indices[cornerIndex] = index;
			}
		}
		if (submesh.knownTriangles.insert(t).second) {
			submesh.indices.push_back(t.indices[0]);
			submesh.indices.push_back(t.indices[1]);
			submesh.indices.push_back(t.indices[2]);
		}
		else {
			std::cout << "duplicate triangle found (and eliminated) in " << fbxNode->GetName() << std::endl;
		}

	}
	std::uint32_t vertexOffset = 0;

	for (auto matIndex = 0u; matIndex < submeshes.size(); ++matIndex) {
		auto& submesh = submeshes[matIndex];
		BabylonSubmesh babsubmesh;
		babsubmesh.indexCount = static_cast<int>(submesh.indices.size());
		babsubmesh.indexStart = static_cast<int>(_indices.size());
		babsubmesh.materialIndex = matIndex;
		babsubmesh.verticesCount = static_cast<int>(submesh.vertices.size());
		babsubmesh.verticesStart = static_cast<int>(_positions.size());
		for (auto& v : submesh.vertices) {
			_positions.push_back(v.position);
			if (normals) {
				_normals.push_back(v.normal);
			}
			if (colors) {
				_colors.push_back(v.color);
			}
			if (uvs) {
				_uvs.push_back(v.uv);
			}
			if (uvs2) {
				_uvs2.push_back(v.uv2);
			}
			if (uvs3) {
				_uvs3.push_back(v.uv3);
			}
			if (uvs4) {
				_uvs4.push_back(v.uv4);
			}
			if (uvs5) {
				_uvs5.push_back(v.uv5);
			}
			if (uvs6) {
				_uvs6.push_back(v.uv6);
			}
			if (skinInfo.hasSkin()){
				 float weight0 = v.boneWeights[0];
				 float weight1 = v.boneWeights[1];
				 float weight2 = v.boneWeights[2];
				 int bone0 = v.boneIndices[0];
				 int bone1 = v.boneIndices[1];
				 int bone2 = v.boneIndices[2];
				 int bone3 = v.boneIndices[3];
               
				_boneWeights.push_back(babylon_vector4( weight0, weight1, weight2, 1.0f - weight0 - weight1 - weight2));
                _boneIndices.push_back((bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0);
			}
		}
		for (auto i : submesh.indices) {
			_indices.push_back(i + vertexOffset);
		}

		vertexOffset = static_cast<int>(_positions.size());
		_submeshes.push_back(babsubmesh);
	}



}
void BaseMesh::GCNormals()
{
    GenerateNormals();
    ColorNormals();
}
Пример #26
0
void Terrain::InitBase(double a_size_x, double a_size_z, int a_res_x, int a_res_z, int n_hill, TerrainType a_type)
{
	
	m_size_x = a_size_x;
	m_size_z = a_size_z;
	m_res_x = a_res_x;
	m_res_z = a_res_z;
	m_dx = m_size_x/m_res_x;
	m_dz = m_size_z/m_res_z;

	m_height_data = new double[(a_res_x+1)*(a_res_z+1)];
	m_normal_data = new Eigen::Vector3f[(a_res_x+1)*(a_res_z+1)];
	for(int i = 0; i < (a_res_x+1)*(a_res_z+1); i++)
		m_height_data[i] = 0.0;//clear to 0
	
	if(a_type == TERRAIN_FLAT){
		for(int ix = 0; ix < (a_res_x+1); ix++)
			for(int iz = 0; iz < (a_res_z+1); iz++){
				m_height_data[ix*(a_res_z+1) + iz] = 0.0;
			}
	}

	else if(a_type == TERRAIN_RANDOM){
		double hill_height_max = 30;
		double hill_center_x, hill_center_z, hill_height, hill_narrowness_x, hill_narrowness_z;
		double dev_x, dev_z;

		for(int i = 0; i < n_hill; i++){	

			hill_center_x = (Util::getRand()-0.5)*a_size_x;
			hill_center_z = (Util::getRand()-0.5)*a_size_z;
			hill_height = Util::getRand()*(hill_height_max - 5) + 5;
			hill_narrowness_x = Util::getRand()*30 + 10; //10~40
			hill_narrowness_z = Util::getRand()*30 + 10; //10~40

			//add the hill to current height map
			for(int ix = 0; ix < (a_res_x+1); ix++)
				for(int iz = 0; iz < (a_res_z+1); iz++){
					dev_x = ix*m_dx - 0.5*a_size_x - hill_center_x;
					dev_z = iz*m_dz - 0.5*a_size_z - hill_center_z;
					m_height_data[ix*(a_res_z+1) + iz] += //guassian hill
						hill_height*exp(-dev_x*dev_x/(2*hill_narrowness_x*hill_narrowness_x)-dev_z*dev_z/(2*hill_narrowness_z*hill_narrowness_z));
				}
		}
	
		//normalize
		double temp_largest = m_height_data[0];
		double temp_smallest = m_height_data[0];
		for(int i = 0; i < (a_res_x+1)*(a_res_z+1); i++)
		{
			if(m_height_data[i] > temp_largest)
				temp_largest = m_height_data[i];
			if(m_height_data[i] < temp_smallest)
				temp_smallest = m_height_data[i];
		}

		for(int i = 0; i < (a_res_x+1)*(a_res_z+1); i++)
		{
			//eventually the range would be from 0~m_hill_height_max
			m_height_data[i] = hill_height_max*(m_height_data[i] - temp_smallest)/temp_largest;
		}


	}else if(a_type == TERRAIN_TEST){
		
		for(int ix = 0; ix < (a_res_x+1); ix++)
			for(int iz = 0; iz < (a_res_z+1); iz++){
				m_height_data[ix*(a_res_z+1) + iz] = 0.0;
			}

	}

	GenerateNormals();
	
}
Пример #27
0
/*
=================
idSurface_Patch::Subdivide
=================
*/
void idSurface_Patch::Subdivide( float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals ) {
	int			i, j, k, l;
	idDrawVert	prev, next, mid;
	idVec3		prevxyz, nextxyz, midxyz;
	idVec3		delta;
	float		maxHorizontalErrorSqr, maxVerticalErrorSqr, maxLengthSqr;

	// generate normals for the control mesh
	if ( genNormals ) {
		GenerateNormals();
	}

	maxHorizontalErrorSqr = Square( maxHorizontalError );
	maxVerticalErrorSqr = Square( maxVerticalError );
	maxLengthSqr = Square( maxLength );

	Expand();

	// horizontal subdivisions
	for ( j = 0; j + 2 < width; j += 2 ) {
		// check subdivided midpoints against control points
		for ( i = 0; i < height; i++ ) {
			for ( l = 0; l < 3; l++ ) {
				prevxyz[l] = verts[i*maxWidth + j+1].xyz[l] - verts[i*maxWidth + j  ].xyz[l];
				nextxyz[l] = verts[i*maxWidth + j+2].xyz[l] - verts[i*maxWidth + j+1].xyz[l];
				midxyz[l] = (verts[i*maxWidth + j  ].xyz[l] + verts[i*maxWidth + j+1].xyz[l] * 2.0f +
														   verts[i*maxWidth + j+2].xyz[l] ) * 0.25f;
			}

			if ( maxLength > 0.0f ) {
				// if the span length is too long, force a subdivision
				if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) {
					break;
				}
			}
			// see if this midpoint is off far enough to subdivide
			delta = verts[i*maxWidth + j+1].xyz - midxyz;
			if ( delta.LengthSqr() > maxHorizontalErrorSqr ) {
				break;
			}
		}

		if ( i == height ) {
			continue;	// didn't need subdivision
		}

		if ( width + 2 >= maxWidth ) {
			ResizeExpanded( maxHeight, maxWidth + 4 );
		}

		// insert two columns and replace the peak
		width += 2;

		for ( i = 0; i < height; i++ ) {
			idSurface_Patch::LerpVert( verts[i*maxWidth + j  ], verts[i*maxWidth + j+1], prev );
			idSurface_Patch::LerpVert( verts[i*maxWidth + j+1], verts[i*maxWidth + j+2], next );
			idSurface_Patch::LerpVert( prev, next, mid );

			for ( k = width - 1; k > j + 3; k-- ) {
				verts[i*maxWidth + k] = verts[i*maxWidth + k-2];
			}
			verts[i*maxWidth + j+1] = prev;
			verts[i*maxWidth + j+2] = mid;
			verts[i*maxWidth + j+3] = next;
		}

		// back up and recheck this set again, it may need more subdivision
		j -= 2;
	}

	// vertical subdivisions
	for ( j = 0; j + 2 < height; j += 2 ) {
		// check subdivided midpoints against control points
		for ( i = 0; i < width; i++ ) {
			for ( l = 0; l < 3; l++ ) {
				prevxyz[l] = verts[(j+1)*maxWidth + i].xyz[l] - verts[j*maxWidth + i].xyz[l];
				nextxyz[l] = verts[(j+2)*maxWidth + i].xyz[l] - verts[(j+1)*maxWidth + i].xyz[l];
				midxyz[l] = (verts[j*maxWidth + i].xyz[l] + verts[(j+1)*maxWidth + i].xyz[l] * 2.0f +
														verts[(j+2)*maxWidth + i].xyz[l] ) * 0.25f;
			}

			if ( maxLength > 0.0f ) {
				// if the span length is too long, force a subdivision
				if ( prevxyz.LengthSqr() > maxLengthSqr || nextxyz.LengthSqr() > maxLengthSqr ) {
					break;
				}
			}
			// see if this midpoint is off far enough to subdivide
			delta = verts[(j+1)*maxWidth + i].xyz - midxyz;
			if ( delta.LengthSqr() > maxVerticalErrorSqr ) {
				break;
			}
		}

		if ( i == width ) {
			continue;	// didn't need subdivision
		}

		if ( height + 2 >= maxHeight ) {
			ResizeExpanded( maxHeight + 4, maxWidth );
		}

		// insert two columns and replace the peak
		height += 2;

		for ( i = 0; i < width; i++ ) {
			LerpVert( verts[j*maxWidth + i], verts[(j+1)*maxWidth + i], prev );
			LerpVert( verts[(j+1)*maxWidth + i], verts[(j+2)*maxWidth + i], next );
			LerpVert( prev, next, mid );

			for ( k = height - 1; k > j + 3; k-- ) {
				verts[k*maxWidth + i] = verts[(k-2)*maxWidth + i];
			}
			verts[(j+1)*maxWidth + i] = prev;
			verts[(j+2)*maxWidth + i] = mid;
			verts[(j+3)*maxWidth + i] = next;
		}

		// back up and recheck this set again, it may need more subdivision
		j -= 2;
	}

	PutOnCurve();

	RemoveLinearColumnsRows();

	Collapse();

	// normalize all the lerped normals
	if ( genNormals ) {
		for ( i = 0; i < width * height; i++ ) {
			verts[i].normal.Normalize();
		}
	}

	GenerateIndexes();
}
Пример #28
0
HeightMap::HeightMap(const std::string& name)
{
	std::ifstream file(name.c_str(), ios::binary);

	if (!file) return;

	numVertices = RAW_WIDTH * RAW_HEIGHT;
	numIndices = (RAW_WIDTH-1) * (RAW_HEIGHT-1)*6;

	vertices = new Vector3[numVertices];
	textureCoords = new Vector2[numVertices];
	colours = new Vector4[numVertices]; //NEW
	indices = new GLuint[numIndices];

	//Load in all char data from file
	unsigned char* data = new unsigned char[numVertices];
	file.read((char*) data, numVertices*sizeof(unsigned char));
	file.close();

	//Create our vertices and texture data from file
	for (int x = 0; x < RAW_WIDTH; ++x){
		for (int z=0; z < RAW_HEIGHT; ++z){
			int offset = (x * RAW_WIDTH) + z;

			//Scaled by a pre determined factor (modifying the terrain loaded 
			//from file)
			vertices[offset] = Vector3(x * HEIGHTMAP_X - (HEIGHTMAP_X * RAW_WIDTH * 0.5f), 
				data[offset] * HEIGHTMAP_Y, z * HEIGHTMAP_Z - (HEIGHTMAP_Z * RAW_HEIGHT * 0.5f));

			/*if (vertices[offset].y < 100.0f)
				colours[offset] = Vector4(0.2f, 0.2f, 0.2f, 0.2f);
			else 
				colours[offset] = Vector4(1.0f, 1.0f, 1.0f, 1.0f);*/

			colours[offset] = Vector4(vertices[offset].y / 200.0f,
				vertices[offset].y / 200.0f, vertices[offset].y / 200.0f,
				vertices[offset].y / 200.0f);

			textureCoords[offset] = Vector2(
				x * HEIGHTMAP_TEX_X, z * HEIGHTMAP_TEX_Z);
		}
	}

	delete data;

	numIndices = 0;

	for (int x = 0; x < RAW_WIDTH-1; ++x){
		for (int z = 0; z < RAW_HEIGHT-1; ++z){
			int a = (x * (RAW_WIDTH)) + z;
			int b = ((x+1) * RAW_WIDTH) + z;
			int c = ((x+1) * RAW_WIDTH) + (z+1);
			int d = (x * RAW_WIDTH) + (z+1);

			indices[numIndices++] = c;
			indices[numIndices++] = b;
			indices[numIndices++] = a;

			indices[numIndices++] = a;
			indices[numIndices++] = d;
			indices[numIndices++] = c;
		}
	}


	GenerateNormals(); //For lighting calculations!
	GenerateTangents(); //For bump mapping! :D
	BufferData();
}
void CMeshSmoothGroups::Apply(CMeshEditor* pcMeshEditor)
{
	GenerateSmoothing(pcMeshEditor);
	GenerateNormals(pcMeshEditor->mpcMesh);
}
Пример #30
0
HeightMap::HeightMap(std::string name) {

	std::ifstream file(name.c_str(), ios::binary);
	if(!file) {
		return;
	}

	type = GL_TRIANGLES ;

	numVertices = RAW_WIDTH*RAW_HEIGHT;
	numIndices = (RAW_WIDTH-1)*(RAW_HEIGHT-1)*6;
	vertices = new Vector3[numVertices];
	textureCoords = new Vector2[numVertices];
	indices = new GLuint[numIndices];

	unsigned char* data = new unsigned char[numVertices];
	file.read((char*)data,numVertices*sizeof(unsigned char));
	file.close();

	// Adding some
	float Min = 1096162876;
	float Max = FLT_MIN;
	//int flag = 0;
	// Min = 0 --- Max = 66048
	for(int x = 0; x < RAW_WIDTH; ++x){
		for(int z = 0; z < RAW_HEIGHT; ++z) {
			int offset = (x * RAW_WIDTH) +z;

			//if(flag == 0){Min = offset;flag++;}


			float height =  data[offset] * HEIGHT_Y;

			vertices[offset] = Vector3(x * HEIGHT_X, data[offset] * HEIGHT_Y, z * HEIGHT_Z);
			//cout << height << endl;
			//if(height < 90){
				//colour[offset] = 
			textureCoords[offset] = Vector2(x * HEIGHTMAP_TEX_X, z * HEIGHTMAP_TEX_Z);


			if (height > Max)
				Max = height;
			
			if (height < Min)	
				Min = height;
			

		}

	}

	//cout << "MIN : " << Min << "\t MAX: " << Max << endl;

	delete data;

	numIndices = 0;

	for(int x = 0; x < RAW_WIDTH-1; ++x){
		for(int z =0; z < RAW_HEIGHT-1; ++z){
			int a = (x * (RAW_WIDTH)) + z;
			int b = ((x+1) * (RAW_WIDTH)) + z;
			int c = ((x+1) * (RAW_WIDTH)) + (z+1);
			int d = (x * (RAW_WIDTH)) + (z+1);

			indices[numIndices++] = c;
			indices[numIndices++] = b;
			indices[numIndices++] = a;

			indices[numIndices++] = a;
			indices[numIndices++] = d;
			indices[numIndices++] = c;

		}
	}
	//Tutorial 11 A - Lighting
	GenerateNormals();
	GenerateTangents();
	BufferData();
}