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; }
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(); }
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); }
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); }
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); }
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); }
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(); }
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(); }
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(); }
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; }
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; }
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(); }
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(); }
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; };
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(); }
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(); }
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(); }
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(); }
/* ================= 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(); }
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(); }
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(); }
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); }
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(); }
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(); }
/* ================= 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(); }
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); }
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(); }