bool TerrainClass::Initialize(ID3D11Device* device, char* heightMapFilename) { bool result; // Load in the height map for the terrain. result = LoadHeightMap(heightMapFilename); if(!result) { return false; } // Normalize the height of the height map. NormalizeHeightMap(); // Calculate the normals for the terrain data. result = CalculateNormals(); if(!result) { return false; } // Initialize the vertex and index buffer that hold the geometry for the terrain. result = InitializeBuffers(device); if(!result) { return false; } return true; }
void MdlObject::InvalidateRenderData () { CalculateNormals (); if(renderData) renderData->Invalidate (); }
void CBoundBox::Update() { //m_matWorld = m_matRot * m_matScall * m_matTrans; VERTEX *v, *vOrig; m_vCenterPoint.x = 0.f; m_vCenterPoint.y = 0.f; m_vCenterPoint.z = 0.f; D3DXMATRIXA16 matPos; D3DXMatrixTranslation(&matPos,0,m_fHeight/2,0); D3DXMatrixMultiply(&m_matWorld,&m_matWorld,&matPos); D3DXVec3TransformCoord( &m_vCenterPoint, &m_vCenterPoint, &m_matWorld ); m_boxOrig->LockVertexBuffer( 0, (void**)&vOrig ); m_box->LockVertexBuffer( 0, (void**)&v ); static D3DXVECTOR3 vec; int i = 0; while( i<24 ) { vec.x = vOrig[i].x; vec.y = vOrig[i].y /*+ fabs( vOrig[i].y )*/; vec.z = vOrig[i].z; D3DXVec3TransformCoord( &vec, &vec, &m_matWorld ); v[i].x = vec.x; v[i].y = vec.y; v[i].z = vec.z; v[i].color = 0xffff00ff; m_vertices[i] = vec; i++; } m_box->UnlockVertexBuffer(); m_boxOrig->UnlockVertexBuffer(); CalculatePlanes(); CalculateNormals(); }
bool ConvexHull::LoadShape(const char* fileName) { std::ifstream load(fileName); if(!load) { load.close(); std::cout << "Could not load convex hull \"" << fileName << "\"!" << std::endl; return false; } else { while(!load.eof()) { std::string firstElement, secondElement; load >> firstElement >> secondElement; if(firstElement.size() == 0 || secondElement.size() == 0) break; m_vertices.push_back(Vec2f(GetFloatVal(firstElement), GetFloatVal(secondElement))); } load.close(); } CenterHull(); CalculateNormals(); return true; }
void MaterialShellObject::AppendData(const std::vector<glm::vec3>& vertices, const std::vector<glm::ivec3>& indices, const Material& material) { // Calculate and copy normals std::vector<glm::vec3> normals(vertices.size(), glm::vec3(0.0, 0.0, 0.0)); CalculateNormals(vertices, indices, normals); AppendData(vertices, normals, indices, material); }
void Mesh::StdDist() { double sumDists = 0.0; for (int v=0; v < vertices.size(); ++v) { sumDists += vertices.at(v).norm(); } const float averageDist = sumDists / vertices.size(); for (int v=0; v < vertices.size(); ++v) { vertices.at(v) /= averageDist; } CalculateNormals(); }
void Mesh::Center() { Vec3f sum(0.0f, 0.0f, 0.0f); for (int v=0; v < vertices.size(); ++v) { sum += vertices.at(v); } const Vec3f center = sum / vertices.size(); for (int v=0; v < vertices.size(); ++v) { vertices.at(v) -= center; } CalculateNormals(); }
Terrain::Terrain(float posx, float posz, int seed, std :: string location){ x = posx; Generate(posx, posz, seed); Create(posx, posz); CalculateNormals(); //Texture tex; //CTexture *Texture; //Texture = new CTexture(); //Texture->LoadTexture(&location[0], &tex); //textures = &tex; //textureID = textures->texID; }
Mesh::Mesh( vector<Vec3f> vertices, int edges, vector< vector<int> > faces) : vertices(vertices) , edges(edges) , faces(faces) , smooth(true) , surfaceDependentNormalWeighting(true) , renderNormals(false) { CalculateNormals(); }
void mx_LevelGenerator::Generate() { MX_ASSERT( room_count_ == 0 ); MX_ASSERT( connection_count_ == 0 ); PlaceRooms(); PlaceConnections(); CalculateLinkage(); GenerateMeshes(); CalculateNormals(); CalculateTextureCoordinates(); SetupTextures(); }
HRESULT Heightmap::init(ID3D11Device* device,ID3D11DeviceContext* deviceContext,Shader* shader,char* heightMapPath, DWORD m, DWORD n, float dx) { HRESULT hr = S_OK; mDevice = device; mDeviceContext = deviceContext; mShader = shader; hr = D3DX11CreateShaderResourceViewFromFile(device,"../Textures/ggrass.dds",0,0,&mAlbedoMap,0); mNumRows = m; mNumCols = n; mCellSpacing = dx; mNumVertices = mNumRows*mNumCols; mNumFaces = (mNumRows-1)*(mNumCols-1)*2; mHeightOffset = -1.5; mHeightScale = 0.25; loadHeightMap(heightMapPath); smooth(); Vertex* vertexArray = new Vertex[mNumVertices]; float halfWidth = (mNumCols-1)*mCellSpacing*0.5f; float halfDepth = (mNumRows-1)*mCellSpacing*0.5f; float du = 1.0f / (mNumCols-1); float dv = 1.0f / (mNumRows-1); for(DWORD i = 0; i < mNumRows; ++i) { float z = halfDepth - i*dx; for(DWORD j = 0; j < mNumCols; ++j) { int vIndex = i*mNumCols+j; vertexArray[vIndex].pos = D3DXVECTOR3(-halfWidth + j*dx, mHeightmap[i*mNumCols+j]-5, z); vertexArray[vIndex].texC = D3DXVECTOR2(j*du, i*dv); vertexArray[vIndex].normal = D3DXVECTOR3(); } } CalculateNormals(vertexArray); InitBuffers(vertexArray); delete vertexArray; return hr; }
bool TerrainClass::InitializeTerrain(ID3D11Device* device, int terrainWidth, int terrainHeight) { int index; float height = 0.0; bool result; // Save the dimensions of the terrain. m_terrainWidth = terrainWidth; m_terrainHeight = terrainHeight; // Create the structure to hold the terrain data. m_heightMap = new HeightMapType[m_terrainWidth * m_terrainHeight]; if(!m_heightMap) { return false; } // Initialise the data in the height map (flat). for(int j=0; j<m_terrainHeight; j++) { for(int i=0; i<m_terrainWidth; i++) { index = (m_terrainHeight * j) + i; m_heightMap[index].x = (float)i; m_heightMap[index].y = (float)height; m_heightMap[index].z = (float)j; } } //even though we are generating a flat terrain, we still need to normalise it. // Calculate the normals for the terrain data. result = CalculateNormals(); if(!result) { return false; } // Initialize the vertex and index buffer that hold the geometry for the terrain. result = InitializeBuffers(device); if(!result) { return false; } return true; }
void Object::Finish(bool bIsDynamic) { if (isFinished || !isCreated) { return; } isDynamic = bIsDynamic; if (isEnvmapped) { isDynamic = true; } pyramid->CreateVertexBuffer(nrVertices, sizeof(OBJECT_VERTEX), OBJECT_VERTEX_FVF, isDynamic, false, &vertexBuffer); pyramid->CreateIndexBuffer(nrFaces, false, false, &indexBuffer); if (doCalculateNormals) { CalculateNormals(); } /*if (doPerPixelLighting) { if (tangent == NULL) { tangent = new OBJECT_TANGENT[nrVertices]; } if (vertexBufferTangent == NULL) { pyramid->CreateVertexBuffer(nrVertices, sizeof(OBJECT_TANGENT), 0, isDynamic, false, &vertexBufferTangent); } CalculateTangents(); vertexBufferTangent->Update(tangent); }*/ vertexBuffer->Update(vertex); indexBuffer->Update(face); isFinished = true; }
bool TerrainClass::Initialize(ID3D11Device* device, char* heightMapFilename, WCHAR* colorTextureFilename, WCHAR* normalMapFilename) { bool result; // Load in the height map for the terrain. result = LoadHeightMap(heightMapFilename); if(!result) { return false; } // Reduce the height of the height map. ReduceHeightMap(); // Calculate the normals for the terrain data. result = CalculateNormals(); if(!result) { return false; } // Construct a 3D model from the height map and normal data. result = BuildTerrainModel(); if(!result) { return false; } // Calculate the normal, tangent, and binormal vectors for the terrain model. CalculateTerrainVectors(); // Initialize the vertex and index buffer for the terrain. result = InitializeBuffers(device); if(!result) { return false; } // Load the textures. result = LoadTextures(device, colorTextureFilename, normalMapFilename); if(!result) { return false; } return true; }
void Object::Refresh() { if (doCalculateNormals) { CalculateNormals(); } //if (doPerPixelLighting) //{ // CalculateTangents(); // vertexBufferTangent->Update(tangent); //} vertexBuffer->Update(vertex, 0, nrVertices * sizeof(OBJECT_VERTEX)); indexBuffer->Update(face, 0, nrFaces * sizeof(OBJECT_FACE)); }
Terrain::Terrain(const char* filename) { // Load height map from file int components; unsigned char* data; data = stbi_load(filename, &width, &height, &components, 0); if (data == NULL) Log() << "Couldn't load image: " << filename << "\n"; // Convert height map to float. heightMap = new float*[width]; normals = new glm::vec3*[width]; tangents = new glm::vec3*[width]; for (int i = 0; i < width; i++) { heightMap[i] = new float[height]; normals[i] = new glm::vec3[height]; tangents[i] = new glm::vec3[height]; } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { heightMap[x][y] = data[(x + y*width)*components] / 256.f; } } stbi_image_free(data); Filter3x3(); CalculateNormals(); GenerateVertices(); GenerateIndices(); for (int i = 0; i < width; i++) { delete[] normals[i]; delete[] tangents[i]; } delete[] normals; delete[] tangents; GenerateBuffers(); GenerateVertexArray(); }
bool TerrainClass::Initialize(ID3D10Device* device, char* heightMapFilename, WCHAR* textureFilename) { bool result; // Load in the height map for the terrain. result = LoadHeightMap(heightMapFilename); if (!result) { return false; } // Normalize the height of the height map. NormalizeHeightMap(); // Calculate the normals for the terrain data. result = CalculateNormals(); if (!result) { return false; } // Calculate the texture coordinates. CalculateTextureCoordinates(); // Load the texture. result = LoadTexture(device, textureFilename); if (!result) { return false; } // Initialize the vertex array that will hold the geometry for the terrain. result = InitializeBuffers(device); if (!result) { return false; } return true; }
void OBJECT::MeshSmooth(bool Linear) { int *EdgeVertMap = new int[EdgeNum]; for (int x=0; x<EdgeNum; x++) EdgeVertMap[x]=-1; #ifdef INCLUDE_OBJ_BUTTERFLYSMOOTH if (!Linear) { for (int x=0; x<VertexNum; x++) VertexList[x].MapTransformedPosition=VertexList[x].Position; CalculateNormals(); SortVertexEdges(); } #endif TessellateEdges(EdgeVertMap, Linear); BuildNewFaces(EdgeVertMap, Linear); delete EdgeVertMap; CalculateTextureCoordinates(); }
void Model_3DS::Load(char *name) { // holds the main chunk header ChunkHeader main; // strip "'s if (strstr(name, "\"")) name = strtok(name, "\""); // Find the path if (strstr(name, "/") || strstr(name, "\\")) { // Holds the name of the model minus the path char *temp; // Find the name without the path if (strstr(name, "/")) temp = strrchr(name, '/'); else temp = strrchr(name, '\\'); // Allocate space for the path path = new char[strlen(name)-strlen(temp)+1]; // Get a pointer to the end of the path and name char *src = name + strlen(name) - 1; // Back up until a \ or the start while (src != path && !((*(src-1)) == '\\' || (*(src-1)) == '/')) src--; // Copy the path into path memcpy (path, name, src-name); path[src-name] = 0; } // Load the file bin3ds = fopen(name,"rb"); //check if file exists if(bin3ds == NULL) { fprintf(stderr, "file couldn't open"); exit(EXIT_FAILURE); } // Make sure we are at the beginning fseek(bin3ds, 0, SEEK_SET); // Load the Main Chunk's header fread(&main.id,sizeof(main.id),1,bin3ds); fread(&main.len,sizeof(main.len),1,bin3ds); // Start Processing MainChunkProcessor(main.len, ftell(bin3ds)); // Don't need the file anymore so close it fclose(bin3ds); // Calculate the vertex normals CalculateNormals(); // For future reference modelname = name; // Find the total number of faces and vertices totalFaces = 0; totalVerts = 0; for (int i = 0; i < numObjects; i ++) { totalFaces += Objects[i].numFaces/3; totalVerts += Objects[i].numVerts; } // If the object doesn't have any texcoords generate some for (int k = 0; k < numObjects; k++) { if (Objects[k].numTexCoords == 0) { // Set the number of texture coords Objects[k].numTexCoords = Objects[k].numVerts; // Allocate an array to hold the texture coordinates Objects[k].TexCoords = new GLfloat[Objects[k].numTexCoords * 2]; // Make some texture coords for (int m = 0; m < Objects[k].numTexCoords; m++) { Objects[k].TexCoords[2*m] = Objects[k].Vertexes[3*m]; Objects[k].TexCoords[2*m+1] = Objects[k].Vertexes[3*m+1]; } } } // Let's build simple colored textures for the materials w/o a texture for (int j = 0; j < numMaterials; j++) { if (Materials[j].textured == false) { unsigned char r = Materials[j].color.r; unsigned char g = Materials[j].color.g; unsigned char b = Materials[j].color.b; Materials[j].tex.BuildColorTexture(r, g, b); Materials[j].textured = true; } } }
void OpenglProject::RenderHeightMap() { GLfloat mat_ambient[] = {0.2, 0.2, 1.0, 1}; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient); glPushMatrix(); glTranslatef(scene.heightmap_position.position.x, scene.heightmap_position.position.y,scene.heightmap_position.position.z); Vector3 axis; real_t angle; scene.heightmap_position.orientation.to_axis_angle(&axis, &angle); glRotatef(angle * 180 / PI, axis.x, axis.y, axis.z); glScalef(scene.heightmap_position.scale.x, scene.heightmap_position.scale.y, scene.heightmap_position.scale.z); int xResolution = 160; int zResolution = 160; float* vertex_array = new float[xResolution * zResolution * 3]; for(int ix =0; ix<xResolution; ix++) for(int iz = 0; iz < zResolution; iz++) { float fx = ix * 2.0f / xResolution - 1.0f; float fz = iz * 2.0f / zResolution - 1.0f; Vector2 vec = Vector2(fx, fz); float fy = scene.heightmap->compute_height(vec); vertex_array[(ix * zResolution + iz) * 3 ] = fx; vertex_array[(ix * zResolution + iz) * 3 + 1] = fy; vertex_array[(ix * zResolution + iz) * 3 + 2] = fz; } Vector3 normals[160][160]; CalculateNormals(normals, xResolution, zResolution, vertex_array); float* normal_array = new float[xResolution * zResolution * 3]; for(int ix =0; ix<xResolution; ix++) for(int iz = 0; iz < zResolution; iz++) { normal_array[(ix * zResolution + iz) * 3 ] = normals[ix][iz].x; normal_array[(ix * zResolution + iz) * 3 + 1] = normals[ix][iz].y; normal_array[(ix * zResolution + iz) * 3 + 2] = normals[ix][iz].z; } GLuint* indices_array = new GLuint[(xResolution - 1) * (zResolution - 1) * 3 * 2]; int index = 0; for(int ix = 0; ix < xResolution-1; ix++) { for(int iz = 0; iz < zResolution-1; iz++) { indices_array[index++] = ix * zResolution + iz; indices_array[index++] = ix * zResolution + iz + 1; indices_array[index++] = (ix+1) * zResolution + iz; } } for(int ix = 1; ix < xResolution; ix++) { for(int iz = 1; iz < zResolution; iz++) { indices_array[index++] = ix * zResolution + iz; indices_array[index++] = ix * zResolution + iz - 1; indices_array[index++] = (ix-1) * zResolution + iz; } } glVertexPointer(3, GL_FLOAT, 0, vertex_array); glNormalPointer(GL_FLOAT, 0, normal_array); glDrawElements(GL_TRIANGLES, 3 * (xResolution - 1) * (zResolution - 1) * 2 , GL_UNSIGNED_INT, indices_array); glPopMatrix(); }
template <class T> void CIsoSurface<T>::GenerateSurface(const T* ptScalarField, T tIsoLevel, unsigned int nCellsX, unsigned int nCellsY, unsigned int nCellsZ, float fCellLengthX, float fCellLengthY, float fCellLengthZ) { if (m_bValidSurface) DeleteSurface(); m_tIsoLevel = tIsoLevel; m_nCellsX = nCellsX; m_nCellsY = nCellsY; m_nCellsZ = nCellsZ; m_fCellLengthX = fCellLengthX; m_fCellLengthY = fCellLengthY; m_fCellLengthZ = fCellLengthZ; m_ptScalarField = ptScalarField; unsigned int nPointsInXDirection = (m_nCellsX + 1); unsigned int nPointsInSlice = nPointsInXDirection*(m_nCellsY + 1); // Generate isosurface. for (unsigned int z = 0; z < m_nCellsZ; z++) for (unsigned int y = 0; y < m_nCellsY; y++) for (unsigned int x = 0; x < m_nCellsX; x++) { // Calculate table lookup index from those // vertices which are below the isolevel.% unsigned int tableIndex = 0; if (m_ptScalarField[z*nPointsInSlice + y*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 1; if (m_ptScalarField[z*nPointsInSlice + (y+1)*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 2; if (m_ptScalarField[z*nPointsInSlice + (y+1)*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 4; if (m_ptScalarField[z*nPointsInSlice + y*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 8; if (m_ptScalarField[(z+1)*nPointsInSlice + y*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 16; if (m_ptScalarField[(z+1)*nPointsInSlice + (y+1)*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 32; if (m_ptScalarField[(z+1)*nPointsInSlice + (y+1)*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 64; if (m_ptScalarField[(z+1)*nPointsInSlice + y*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 128; // Now create a triangulation of the isosurface in this // cell. if (m_edgeTable[tableIndex] != 0) { if (m_edgeTable[tableIndex] & 8) { POINT3DID pt = CalculateIntersection(x, y, z, 3); unsigned int id = GetEdgeID(x, y, z, 3); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 1) { POINT3DID pt = CalculateIntersection(x, y, z, 0); unsigned int id = GetEdgeID(x, y, z, 0); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 256) { POINT3DID pt = CalculateIntersection(x, y, z, 8); unsigned int id = GetEdgeID(x, y, z, 8); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (x == m_nCellsX - 1) { if (m_edgeTable[tableIndex] & 4) { POINT3DID pt = CalculateIntersection(x, y, z, 2); unsigned int id = GetEdgeID(x, y, z, 2); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 2048) { POINT3DID pt = CalculateIntersection(x, y, z, 11); unsigned int id = GetEdgeID(x, y, z, 11); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if (y == m_nCellsY - 1) { if (m_edgeTable[tableIndex] & 2) { POINT3DID pt = CalculateIntersection(x, y, z, 1); unsigned int id = GetEdgeID(x, y, z, 1); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 512) { POINT3DID pt = CalculateIntersection(x, y, z, 9); unsigned int id = GetEdgeID(x, y, z, 9); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if (z == m_nCellsZ - 1) { if (m_edgeTable[tableIndex] & 16) { POINT3DID pt = CalculateIntersection(x, y, z, 4); unsigned int id = GetEdgeID(x, y, z, 4); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 128) { POINT3DID pt = CalculateIntersection(x, y, z, 7); unsigned int id = GetEdgeID(x, y, z, 7); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if ((x==m_nCellsX - 1) && (y==m_nCellsY - 1)) if (m_edgeTable[tableIndex] & 1024) { POINT3DID pt = CalculateIntersection(x, y, z, 10); unsigned int id = GetEdgeID(x, y, z, 10); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if ((x==m_nCellsX - 1) && (z==m_nCellsZ - 1)) if (m_edgeTable[tableIndex] & 64) { POINT3DID pt = CalculateIntersection(x, y, z, 6); unsigned int id = GetEdgeID(x, y, z, 6); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if ((y==m_nCellsY - 1) && (z==m_nCellsZ - 1)) if (m_edgeTable[tableIndex] & 32) { POINT3DID pt = CalculateIntersection(x, y, z, 5); unsigned int id = GetEdgeID(x, y, z, 5); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } for (unsigned int i = 0; m_triTable[tableIndex][i] != -1; i += 3) { TRIANGLE triangle; unsigned int pointID0, pointID1, pointID2; pointID0 = GetEdgeID(x, y, z, m_triTable[tableIndex][i]); pointID1 = GetEdgeID(x, y, z, m_triTable[tableIndex][i+1]); pointID2 = GetEdgeID(x, y, z, m_triTable[tableIndex][i+2]); triangle.pointID[0] = pointID0; triangle.pointID[1] = pointID1; triangle.pointID[2] = pointID2; m_trivecTriangles.push_back(triangle); } } } RenameVerticesAndTriangles(); CalculateNormals(); m_bValidSurface = true; }
void Object::Render() { if (!isCreated || !isEnabled) { return; } if (!isFinished) { Finish(false); } Matrix matRot, matLoc, matScl; matRot = Matrix::RotateY(rotation.y) * Matrix::RotateZ(rotation.z) * Matrix::RotateX(rotation.x); matLoc = Matrix::Translation(location.x, location.y, location.z); matScl = Matrix::Scale(scale.x, scale.y, scale.z); pyramid->SetWorldMatrix(matScl * matRot * matLoc); if (isDynamic || isEnvmapped) { if (doCalculateNormals) { CalculateNormals(); } if (isEnvmapped) { CalculateEnvmapUV(); } Refresh(); } pyramid->SetMaterial(material); if (material.power > 0.0f) { pyramid->SetRenderState(D3DRS_SPECULARENABLE, true); } else { pyramid->SetRenderState(D3DRS_SPECULARENABLE, false); } pyramid->SetCullMode(cullMode); if (texture != NULL) { pyramid->SetTexture(texture); } else { pyramid->SetTexture(NULL); } if (lightmap != NULL) { pyramid->SetTexture(lightmap, 1); pyramid->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); pyramid->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); } else { pyramid->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); } if (writeZBuffer) { pyramid->SetWriteZBufferEnable(true); } else { pyramid->SetWriteZBufferEnable(false); } pyramid->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); pyramid->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); pyramid->SetTransparency(transMode); pyramid->SetVertexStream(vertexBuffer); pyramid->SetIndexStream(indexBuffer); //if (vertexShader != NULL) //{ // Matrix matView, matProj, matWorld, matTransform, matWorldInverse; // pyramid->GetWorldMatrix(matWorld); // pyramid->GetViewMatrix(matView); // pyramid->GetProjectionMatrix(matProj); // matTransform = (matWorld * matView * matProj).Transpose(); // matWorldInverse = (matWorld.Inverse()).Transpose(); // matWorld = matWorld.Transpose(); // matView = matView.Transpose(); // pyramid->SetVertexShaderConstantF( 0, (float*)&matTransform, 4); // pyramid->SetVertexShaderConstantF( 4, (float*)&matWorld, 4); // pyramid->SetVertexShaderConstantF( 8, (float*)&matWorldInverse, 4); // pyramid->SetVertexShaderConstantF(12, (float*)&matView, 4); // float power[] = {material.power, 0, 0, 0}; // pyramid->SetVertexShaderConstantF(40, (float*)&material.diffuse, 4); // pyramid->SetVertexShaderConstantF(41, (float*)&material.specular, 4); // pyramid->SetVertexShaderConstantF(42, (float*)&material.emissive, 4); // pyramid->SetVertexShaderConstantF(43, (float*)&power, 4); // pyramid->SetVertexShader(vertexShader); //} //if (pixelShader != NULL) //{ // pyramid->SetPixelShader(pixelShader); //} //if (doPerPixelLighting) //{ // pyramid->SetVertexStream(vertexBufferTangent, 1); //} pyramid->DrawIndexedPrimitiveList(0, nrVertices, 0, nrFaces); pyramid->SetPixelShader(NULL); // pyramid->SetVertexShader(NULL); pyramid->SetVertexStream(NULL, 1); }
IMeshSceneNode* CustomSceneNodeManager::CreateCylinderSceneNode(scene::ISceneManager* sceneManager, s32 id, SColor& color, unsigned int resolution, float radius, float height) { /*if (!cylinderMesh) {*/ if (resolution >= 4) { SMesh* newCylinderMesh = new SMesh(); SMeshBuffer* buf = new SMeshBuffer(); newCylinderMesh->addMeshBuffer(buf); buf->MappingHint_Vertex = EHM_STATIC; buf->MappingHint_Index = EHM_STATIC; buf->drop(); int noWarningSignedResolution = resolution; float currentTheta = 0.0f; float skipAmount = 2.0f*PI / (float)resolution; float halfHeight = height / 2.0f; S3DVertex temp1 = S3DVertex(Vector3(0.0f, halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 0.0f)); S3DVertex temp2 = S3DVertex(Vector3(0.0f, -halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 1.0f)); for(int i = 0; i < noWarningSignedResolution; i++) { float x = cosf(currentTheta) * radius; float z = sinf(currentTheta) * radius; temp1.Pos.X = x; temp1.Pos.Z = z; temp1.TCoords.X = currentTheta / 2.0f*PI; temp2.Pos.X = x; temp2.Pos.Z = z; temp2.TCoords.X = currentTheta / 2.0f*PI; buf->Vertices.push_back(temp1); buf->Vertices.push_back(temp2); currentTheta += skipAmount; } temp1.Pos.X = 0.0f; temp1.Pos.Z = 0.0f; temp1.TCoords.X = 0.0f; temp2.Pos.X = 0.0f; temp2.Pos.Z = 0.0f; temp1.TCoords.X = 0.0f; buf->Vertices.push_back(temp1); buf->Vertices.push_back(temp2); //Get indices for(int i = 0; i < noWarningSignedResolution - 1; i++) { buf->Indices.push_back(i*2); buf->Indices.push_back(i*2+2); buf->Indices.push_back(i*2+1); buf->Indices.push_back(i*2+1); buf->Indices.push_back(i*2+2); buf->Indices.push_back(i*2+3); buf->Indices.push_back(i*2); buf->Indices.push_back(buf->Vertices.size()-2); buf->Indices.push_back(i*2+2); buf->Indices.push_back(i*2+1); buf->Indices.push_back(i*2+3); buf->Indices.push_back(buf->Vertices.size()-1); } buf->Indices.push_back(buf->Vertices.size()-4); buf->Indices.push_back(0); buf->Indices.push_back(buf->Vertices.size()-3); buf->Indices.push_back(buf->Vertices.size()-3); buf->Indices.push_back(0); buf->Indices.push_back(1); buf->Indices.push_back(buf->Vertices.size()-4); buf->Indices.push_back(buf->Vertices.size()-2); buf->Indices.push_back(0); buf->Indices.push_back(buf->Vertices.size()-3); buf->Indices.push_back(1); buf->Indices.push_back(buf->Vertices.size()-1); //Calculate normals CalculateNormals(buf->Vertices, buf->Indices); buf->recalculateBoundingBox(); newCylinderMesh->recalculateBoundingBox(); IMeshSceneNode* node = sceneManager->addMeshSceneNode(newCylinderMesh); newCylinderMesh->drop(); return node; } /* return NULL; } else { IMeshSceneNode* node = sceneManager->addMeshSceneNode(cylinderMesh); node->setScale(Vector3(radius, height, radius)); return node; }*/ return NULL; }
IMeshSceneNode* CustomSceneNodeManager::CreateCapsuleSceneNode(scene::ISceneManager* sceneManager, s32 id, SColor& color, unsigned int resolution, float radius, float heightFromSphereCenters) { if (resolution >= 4) { SMesh* newCapsuleMesh = new SMesh(); SMeshBuffer* buf = new SMeshBuffer(); newCapsuleMesh->addMeshBuffer(buf); buf->MappingHint_Vertex = EHM_STATIC; buf->MappingHint_Index = EHM_STATIC; buf->drop(); int noWarningSignedResolution = resolution; float thetaSkipAmount = 2.0f*PI / (float)resolution; float halfHeight = heightFromSphereCenters / 2.0f; float phiSkipAmount = PI*0.5f / (float)resolution; S3DVertex temp1 = S3DVertex(Vector3(0.0f, halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 0.0f)); S3DVertex temp2 = S3DVertex(Vector3(0.0f, -halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 1.0f)); float currentTheta = 0.0f; float currentPhi = phiSkipAmount; temp1.Pos.Y = halfHeight + radius; buf->Vertices.push_back(temp1); //Semi-sphere Tips for(unsigned int i = 1; i < resolution; i++) { for(unsigned int j = 0; j < resolution; j++) { float x = sinf(currentPhi) * cosf(currentTheta) * radius; float y = cosf(currentPhi) * radius; float z = sinf(currentPhi) * sinf(currentTheta) * radius; temp1.Pos.X = x; temp1.Pos.Y = y + halfHeight; temp1.Pos.Z = z; temp1.TCoords.X = currentTheta / 2.0f*PI; temp1.TCoords.Y = currentPhi / PI; buf->Vertices.push_back(temp1); currentTheta += thetaSkipAmount; } currentTheta = 0.0f; currentPhi += phiSkipAmount; } currentTheta = 0.0f; currentPhi = PI/2.0f; //Semi-sphere Tips for(unsigned int i = 1; i < resolution; i++) { for(unsigned int j = 0; j < resolution; j++) { float x = sinf(currentPhi) * cosf(currentTheta) * radius; float y = cosf(currentPhi) * radius; float z = sinf(currentPhi) * sinf(currentTheta) * radius; temp1.Pos.X = x; temp1.Pos.Y = y - halfHeight; temp1.Pos.Z = z; temp1.TCoords.X = currentTheta / 2.0f*PI; temp1.TCoords.Y = currentPhi / PI; buf->Vertices.push_back(temp1); currentTheta += thetaSkipAmount; } currentTheta = 0.0f; currentPhi += phiSkipAmount; } temp1.Pos.X = 0.0f; temp1.Pos.Y = -(halfHeight + radius); temp1.Pos.Z = 0.0f; buf->Vertices.push_back(temp1); //Top vertex indices for(unsigned int i = 1; i <= resolution; i++) { if (i == resolution) { buf->Indices.push_back(i); buf->Indices.push_back(0); buf->Indices.push_back(1); } else { buf->Indices.push_back(i); buf->Indices.push_back(0); buf->Indices.push_back(i + 1); } } //Get indices int i = 1 + resolution; while(i < buf->Vertices.size() - 1) { for(unsigned int j = 1; j < resolution; j++) { buf->Indices.push_back(i); buf->Indices.push_back(i - noWarningSignedResolution); buf->Indices.push_back(i - noWarningSignedResolution + 1); buf->Indices.push_back(i); buf->Indices.push_back(i - noWarningSignedResolution + 1); buf->Indices.push_back(i + 1); i++; } buf->Indices.push_back(i); buf->Indices.push_back(i - noWarningSignedResolution); buf->Indices.push_back(i - noWarningSignedResolution + 1 - resolution); buf->Indices.push_back(i); buf->Indices.push_back(i - noWarningSignedResolution + 1 - resolution); buf->Indices.push_back(i + 1 - resolution); i++; } //Bottom vertex indices for(int i = resolution; i >= 1 ; i--) { if (i == 1) { /*buf->Indices.push_back(i); buf->Indices.push_back(0); buf->Indices.push_back(1);*/ buf->Indices.push_back(buf->Vertices.size() -1); buf->Indices.push_back(buf->Vertices.size() -1 - i); buf->Indices.push_back(buf->Vertices.size() - 1 - resolution); } else { buf->Indices.push_back(buf->Vertices.size() -1); buf->Indices.push_back(buf->Vertices.size() -1 - i); buf->Indices.push_back(buf->Vertices.size() - i); } } //Calculate normals CalculateNormals(buf->Vertices, buf->Indices); buf->recalculateBoundingBox(); newCapsuleMesh->recalculateBoundingBox(); IMeshSceneNode* node = sceneManager->addMeshSceneNode(newCapsuleMesh); newCapsuleMesh->drop(); return node; } return NULL; }
cRenderWorker::sRayRecursionOut cRenderWorker::RayRecursion(sRayRecursionIn in, sRayRecursionInOut &inOut) { sRayMarchingOut rayMarchingOut; *inOut.rayMarchingInOut.buffCount = 0; //trace the light in given direction CVector3 point = RayMarching(in.rayMarchingIn, &inOut.rayMarchingInOut, &rayMarchingOut); sRGBAfloat resultShader = in.resultShader; sRGBAfloat objectColour = in.objectColour; //here will be called branch for RayRecursion(); sRGBAfloat objectShader; objectShader.A = 0.0; sRGBAfloat backgroundShader; sRGBAfloat volumetricShader; sRGBAfloat specular; //prepare data for shaders CVector3 lightVector = shadowVector; sShaderInputData shaderInputData; shaderInputData.distThresh = rayMarchingOut.distThresh; shaderInputData.delta = CalcDelta(point); shaderInputData.lightVect = lightVector; shaderInputData.point = point; shaderInputData.viewVector = in.rayMarchingIn.direction; shaderInputData.lastDist = rayMarchingOut.lastDist; shaderInputData.depth = rayMarchingOut.depth; shaderInputData.stepCount = *inOut.rayMarchingInOut.buffCount; shaderInputData.stepBuff = inOut.rayMarchingInOut.stepBuff; shaderInputData.invertMode = in.calcInside; shaderInputData.objectId = rayMarchingOut.objectId; cObjectData objectData = data->objectData[shaderInputData.objectId]; shaderInputData.material = &data->materials[objectData.materialId]; sRGBAfloat reflectShader = in.resultShader; double reflect = shaderInputData.material->reflectance; sRGBAfloat transparentShader = in.resultShader; double transparent = shaderInputData.material->transparencyOfSurface; sRGBfloat transparentColor = sRGBfloat(shaderInputData.material->transparencyInteriorColor.R / 65536.0, shaderInputData.material->transparencyInteriorColor.G / 65536.0, shaderInputData.material->transparencyInteriorColor.B / 65536.0); resultShader.R = transparentColor.R; resultShader.G = transparentColor.G; resultShader.B = transparentColor.B; CVector3 vn; //if found any object if (rayMarchingOut.found) { //calculate normal vector vn = CalculateNormals(shaderInputData); shaderInputData.normal = vn; if(shaderInputData.material->diffusionTexture.IsLoaded()) shaderInputData.texDiffuse = TextureShader(shaderInputData, cMaterial::texDiffuse, shaderInputData.material); else shaderInputData.texDiffuse = sRGBfloat(1.0, 1.0, 1.0); if(shaderInputData.material->normalMapTexture.IsLoaded()) { vn = NormalMapShader(shaderInputData); } //prepare refraction values double n1, n2; if (in.calcInside) //if trance is inside the object { n1 = shaderInputData.material ->transparencyIndexOfRefraction; //reverse refractive indices n2 = 1.0; } else { n1 = 1.0; n2 = shaderInputData.material ->transparencyIndexOfRefraction; ; } if (inOut.rayIndex < reflectionsMax) { //calculate refraction (transparency) if (transparent > 0.0) { sRayRecursionIn recursionIn; sRayMarchingIn rayMarchingIn; sRayMarchingInOut rayMarchingInOut; //calculate direction of refracted light CVector3 newDirection = RefractVector(vn, in.rayMarchingIn.direction, n1, n2); //move starting point a little CVector3 newPoint = point + in.rayMarchingIn.direction * shaderInputData.distThresh * 1.0; //if is total internal reflection the use reflection instead of refraction bool internalReflection = false; if (newDirection.Length() == 0.0) { newDirection = ReflectionVector(vn, in.rayMarchingIn.direction); newPoint = point + in.rayMarchingIn.direction * shaderInputData.distThresh * 1.0; internalReflection = true; } //preparation for new recursion rayMarchingIn.binaryEnable = true; rayMarchingIn.direction = newDirection; rayMarchingIn.maxScan = params->viewDistanceMax; rayMarchingIn.minScan = 0.0; rayMarchingIn.start = newPoint; rayMarchingIn.invertMode = !in.calcInside || internalReflection; recursionIn.rayMarchingIn = rayMarchingIn; recursionIn.calcInside = !in.calcInside || internalReflection; recursionIn.resultShader = resultShader; recursionIn.objectColour = objectColour; //setup buffers for ray data inOut.rayIndex++; //increase recursion index rayMarchingInOut.buffCount = &rayBuffer[inOut.rayIndex].buffCount; rayMarchingInOut.stepBuff = rayBuffer[inOut.rayIndex].stepBuff; inOut.rayMarchingInOut = rayMarchingInOut; //recursion for refraction sRayRecursionOut recursionOutTransparent = RayRecursion(recursionIn, inOut); transparentShader = recursionOutTransparent.resultShader; } //calculate reflection if (reflect > 0.0) { sRayRecursionIn recursionIn; sRayMarchingIn rayMarchingIn; sRayMarchingInOut rayMarchingInOut; //calculate new direction of reflection CVector3 newDirection = ReflectionVector(vn, in.rayMarchingIn.direction); CVector3 newPoint = point + newDirection * shaderInputData.distThresh; //prepare for new recursion rayMarchingIn.binaryEnable = true; rayMarchingIn.direction = newDirection; rayMarchingIn.maxScan = params->viewDistanceMax; rayMarchingIn.minScan = 0.0; rayMarchingIn.start = newPoint; rayMarchingIn.invertMode = false; recursionIn.rayMarchingIn = rayMarchingIn; recursionIn.calcInside = false; recursionIn.resultShader = resultShader; recursionIn.objectColour = objectColour; //setup buffers for ray data inOut.rayIndex++; //increase recursion index rayMarchingInOut.buffCount = &rayBuffer[inOut.rayIndex].buffCount; rayMarchingInOut.stepBuff = rayBuffer[inOut.rayIndex].stepBuff; inOut.rayMarchingInOut = rayMarchingInOut; //recursion for reflection sRayRecursionOut recursionOutReflect = RayRecursion(recursionIn, inOut); reflectShader = recursionOutReflect.resultShader; } if (transparent > 0.0) inOut.rayIndex--; //decrease recursion index if (reflect > 0.0) inOut.rayIndex--; //decrease recursion index } shaderInputData.normal = vn; //calculate effects for object surface objectShader = ObjectShader(shaderInputData, &objectColour, &specular); //calculate reflectance according to Fresnel equations double reflectance = 1.0; double reflectanceN = 1.0; if (shaderInputData.material->fresnelReflectance) { reflectance = Reflectance(vn, in.rayMarchingIn.direction, n1, n2); if (reflectance < 0.0) reflectance = 0.0; if (reflectance > 1.0) reflectance = 1.0; reflectanceN = 1.0 - reflectance; } //combine all results resultShader.R = (objectShader.R + specular.R); resultShader.G = (objectShader.G + specular.G); resultShader.B = (objectShader.B + specular.B); if (reflectionsMax > 0) { sRGBfloat reflectDiffused; double diffIntes = shaderInputData.material->diffussionTextureIntensity; double diffIntesN = 1.0 - diffIntes; reflectDiffused.R = reflect * shaderInputData.texDiffuse.R * diffIntes + reflect * diffIntesN; reflectDiffused.G = reflect * shaderInputData.texDiffuse.G * diffIntes + reflect * diffIntesN; reflectDiffused.B = reflect * shaderInputData.texDiffuse.B * diffIntes + reflect * diffIntesN; resultShader.R = transparentShader.R * transparent * reflectanceN + (1.0 - transparent * reflectanceN) * resultShader.R; resultShader.G = transparentShader.G * transparent * reflectanceN + (1.0 - transparent * reflectanceN) * resultShader.G; resultShader.B = transparentShader.B * transparent * reflectanceN + (1.0 - transparent * reflectanceN) * resultShader.B; resultShader.R = reflectShader.R * reflectDiffused.R * reflectance + (1.0 - reflectDiffused.R * reflectance) * resultShader.R; resultShader.G = reflectShader.G * reflectDiffused.G * reflectance + (1.0 - reflectDiffused.G * reflectance) * resultShader.G; resultShader.B = reflectShader.B * reflectDiffused.B * reflectance + (1.0 - reflectDiffused.B * reflectance) * resultShader.B; } if(resultShader.R < 0.0) resultShader.R = 0.0; if(resultShader.G < 0.0) resultShader.G = 0.0; if(resultShader.B < 0.0) resultShader.B = 0.0; } else //if object not found then calculate background { backgroundShader = BackgroundShader(shaderInputData); resultShader = backgroundShader; shaderInputData.depth = 1e20; vn = mRot.RotateVector(CVector3(0.0, -1.0, 0.0)); } sRGBAfloat opacityOut; if (in.calcInside) //if the object interior is traced, then the absorption of light has to be calculated { for (int index = shaderInputData.stepCount - 1; index > 0; index--) { double step = shaderInputData.stepBuff[index].step; //CVector3 point = shaderInputData.stepBuff[index].point; //shaderInputData.point = point; //sRGBAfloat color = SurfaceColour(shaderInputData); //transparentColor.R = color.R; //transparentColor.G = color.G; //transparentColor.B = color.B; double opacity = -log(shaderInputData.material ->transparencyOfInterior) * step; if (opacity > 1.0) opacity = 1.0; resultShader.R = opacity * transparentColor.R + (1.0 - opacity) * resultShader.R; resultShader.G = opacity * transparentColor.G + (1.0 - opacity) * resultShader.G; resultShader.B = opacity * transparentColor.B + (1.0 - opacity) * resultShader.B; } } else //if now is outside the object, then calculate all volumetric effects like fog, glow... { volumetricShader = VolumetricShader(shaderInputData, resultShader, &opacityOut); resultShader = volumetricShader; } //prepare final result sRayRecursionOut out; out.point = point; out.rayMarchingOut = rayMarchingOut; out.objectColour = objectColour; out.resultShader = resultShader; out.found = (shaderInputData.depth == 1e20) ? false : true; out.fogOpacity = opacityOut.R; out.normal = vn; return out; }
Model<VertexPosNormTanTex>* TerrainLoader::Load(ID3D10Device* pDXDevice, const tstring& key) { Model<VertexPosNormTanTex>* ret = 0; if ( m_pAssets->IsAssetPresent(key)) { ret = m_pAssets->GetAsset(key); } else { vector<VertexPosNormTanTex> vertices; vector<DWORD> indices; Texture2D* heightMap = Content->LoadTexture2D(key, true); ID3D10Texture2D* pTex2D = heightMap->GetTextureResource(); vertices.reserve(heightMap->GetWidth() * heightMap->GetHeight()); indices.reserve((heightMap->GetWidth()-1) * (heightMap->GetHeight()-1) * 6); D3D10_MAPPED_TEXTURE2D pMappedTex2D; pTex2D->Map(0, D3D10_MAP_READ, 0, &pMappedTex2D); float heightMult = 1.0f; float planarMult = 1.0f / max(heightMap->GetWidth(), heightMap->GetHeight()); BYTE* pData = static_cast<BYTE*>(pMappedTex2D.pData); for (UINT x = 0; x < heightMap->GetHeight(); ++x) { for (UINT z = 0; z < heightMap->GetWidth(); ++z) { float height = pData[z * 4 + x * pMappedTex2D.RowPitch + 0] / 255.0f; //get red vertices.push_back(VertexPosNormTanTex( static_cast<float>(x) * planarMult, height * heightMult, static_cast<float>(z) * planarMult, 0, 0, 0, 0, 0, 0, static_cast<float>(z) / heightMap->GetWidth(), static_cast<float>(x) / heightMap->GetHeight())); if (z != heightMap->GetWidth() - 1 && x != heightMap->GetHeight() - 1) { indices.push_back(z + x * heightMap->GetWidth()); indices.push_back(z + x * heightMap->GetWidth() + 1); indices.push_back(z + (x + 1) * heightMap->GetWidth()); indices.push_back(z + x * heightMap->GetWidth() + 1); indices.push_back(z + (x + 1) * heightMap->GetWidth() + 1); indices.push_back(z + (x + 1) * heightMap->GetWidth()); } } } pTex2D->Unmap(0); CalculateNormals(vertices, indices); CalculateTangents(vertices, indices); Model<VertexPosNormTanTex>* pModel = new Model<VertexPosNormTanTex>(pDXDevice); ModelMesh<VertexPosNormTanTex>* pMesh = pModel->AddMesh(_T("")); pMesh->SetVertices(vertices); pMesh->SetIndices(indices); m_pAssets->AddAsset(key, pModel); ret = pModel; } return ret; }
IMeshSceneNode* CustomSceneNodeManager::CreateConeSceneNode(scene::ISceneManager* sceneManager, s32 id, SColor& color, unsigned int resolution, float radius, float height) { if (resolution >= 4) { /*IMesh* newConeMesh = sceneManager->getGeometryCreator()->createConeMesh(radius, height, resolution, color, color); IMeshSceneNode* node = sceneManager->addMeshSceneNode(newConeMesh); sceneManager->getMeshCache()->addMesh(irr::io::path("ConeMesh"), (irr::scene::IAnimatedMesh*)newConeMesh); newConeMesh->drop();*/ SMesh* newConeMesh = new SMesh(); SMeshBuffer* buf = new SMeshBuffer(); newConeMesh->addMeshBuffer(buf); buf->MappingHint_Vertex = EHM_STATIC; buf->MappingHint_Index = EHM_STATIC; buf->drop(); int noWarningSignedResolution = resolution; float currentTheta = 0.0f; float skipAmount = 2.0f*PI / (float)resolution; float halfHeight = height / 2.0f; S3DVertex temp1 = S3DVertex(Vector3(0.0f, halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 0.0f)); S3DVertex temp2 = S3DVertex(Vector3(0.0f, -halfHeight, 0.0f), Vector3_Zero, color, vector2d<f32>(0.0f, 1.0f)); for(int i = 0; i < noWarningSignedResolution; i++) { float x = cosf(currentTheta) * radius; float z = sinf(currentTheta) * radius; temp2.Pos.X = x; temp2.Pos.Z = z; temp2.TCoords.X = currentTheta / 2.0f*PI; buf->Vertices.push_back(temp2); currentTheta += skipAmount; } buf->Vertices.push_back(temp1); //Get side indices for(int i = 0; i < noWarningSignedResolution - 1; i++) { buf->Indices.push_back(i); buf->Indices.push_back(buf->Vertices.size()-1); buf->Indices.push_back(i+1); } buf->Indices.push_back(buf->Vertices.size()-2); buf->Indices.push_back(buf->Vertices.size()-1); buf->Indices.push_back(0); temp2.Pos.X = 0.0f; temp2.Pos.Z = 0.0f; buf->Vertices.push_back(temp2); //Get bottom indices for(int i = 0; i < noWarningSignedResolution - 1; i++) { buf->Indices.push_back(i); buf->Indices.push_back(i+1); buf->Indices.push_back(buf->Vertices.size()-1); } buf->Indices.push_back(buf->Vertices.size()-1); buf->Indices.push_back(buf->Vertices.size()-3); buf->Indices.push_back(0); //Calculate normals CalculateNormals(buf->Vertices, buf->Indices); buf->recalculateBoundingBox(); newConeMesh->recalculateBoundingBox(); IMeshSceneNode* node = sceneManager->addMeshSceneNode(newConeMesh); newConeMesh->drop(); return node; } return NULL; }
// Initialize // // Added tangent & biNormal calculation // bool TerrainClass::Initialize( ID3D11Device* device, int terrainDimension, int smoothingPasses, float displacementValue, WCHAR* textureFileName1, WCHAR* textureFileName2, WCHAR* textureFileName3, WCHAR* textureFileName4, WCHAR* textureFileName5, WCHAR* textureFileName6, WCHAR* textureFileName7, WCHAR* textureFileName8 ) { bool result; /* // Load in the height map for the terrain result = LoadHeightMap( heightMapFileName ); if( !result ) { return false; } // Normalize the height of the height map NormalizeHeightMap(); */ // Initialize Terrain // // Set terrain height & width mTerrainHeight = mTerrainWidth = terrainDimension; // Create the structure to hold the height map data pHeightMap = new HeightMapType[ mTerrainWidth * mTerrainHeight ]; if( !pHeightMap ) { return false; } // Initialize terrain data structre(1.0f height) int index; for( int j = 0; j < mTerrainHeight; j++ ) { for( int i = 0; i < mTerrainWidth; i++ ) { index = ( mTerrainHeight * j ) + i; pHeightMap[ index ].x = ( float )i; pHeightMap[ index ].y = 1.0f; pHeightMap[ index ].z = ( float )j; } } // Generate new terrain DiamondSquareAlgorithm( 10.0f, displacementValue, 2.0f ); // Smooth (5 passes) SmoothHeights( smoothingPasses ); // Calculate the normals for the terrain data result = CalculateNormals(); if( !result ) { return false; } // Calculate the texture coordinates CalculateTextureCoordinates(); // Load the texture result = LoadTextures( device, textureFileName1, textureFileName2, textureFileName3, textureFileName4, textureFileName5, textureFileName6, textureFileName7, textureFileName8 ); if( !result ) { return false; } // Calculate the normal, tangent, and biNormal vectors for the model CalculateModelVectors(); // Initialize the vertex and index buffer that hold the geometry for the terrain result = InitializeBuffers( device ); if( !result ) { return false; } return true; }
void parseOBJ(ElysiumEngine::Mesh *output, FILE *input) { rewind(input); std::vector<std::string> tokens; //Tempoary storage to hold vertex data before duplication std::vector<Vec4> vertices; std::vector<Vec4> indices;//0: position, 1: normal, 2: texture std::vector<Vec4> normals; std::vector<Vec4> texturecoords; //0: position, 1: normal, 2: texture, 3: actual // std::vector<std::tuple<int,int,int,int>> usedIndices; std::vector<ElysiumEngine::VertexData> final; int vertexIndex = 0; int normalIndex = 0; int faceIndex = 0; int textureIndex = 0; char buffer[1000]; ElysiumEngine::Material *current = nullptr; while(!feof(input)) { tokens.clear(); if(!fgets(buffer,1000,input)) { break; } if(buffer[0] == '#') continue; customTokenize(buffer, tokens); if(tokens.empty()) continue; if (tokens[0] == "mtllib") { ElysiumEngine::GraphicsSystem::g_GraphicsSystem->getMaterialLibrary().loadMaterialsFromFile(tokens[1]); //TODO: Additionally apply the current material to vertices as specifed continue; } if(tokens[0] == "v") { if(tokens.size() < 4) { std::cout << "Error each vertex must have a least 3 elements: " << buffer; continue; } output->vertices[vertexIndex].position.x = std::atof(tokens[1].c_str()); output->vertices[vertexIndex].position.y = std::atof(tokens[2].c_str()); output->vertices[vertexIndex].position.z = std::atof(tokens[3].c_str()); output->vertices[vertexIndex].position.w = 0.0f; vertices.push_back(Vec4(std::atof(tokens[1].c_str()),std::atof(tokens[2].c_str()),std::atof(tokens[3].c_str()))); vertexIndex++; } else if(tokens[0] == "vt") { if(tokens.size() < 3) { std::cout << "Error texture coords must have at least 2 elements" << buffer; continue; } // output->vertices[textureIndex].texture[0] = std::atof(tokens[1].c_str()); // output->vertices[textureIndex].texture[1] = std::atof(tokens[2].c_str()); texturecoords.push_back(Vec4(std::atof(tokens[1].c_str()),std::atof(tokens[2].c_str()),0)); textureIndex++; } else if(tokens[0] == "vn") { if(tokens.size() < 4) { std::cout << "Error nomal must have at least 3 elements: " << buffer; continue; } output->vertices[normalIndex].normal.x = std::atof(tokens[1].c_str()); output->vertices[normalIndex].normal.y = std::atof(tokens[2].c_str()); output->vertices[normalIndex].normal.z = std::atof(tokens[3].c_str()); normals.push_back(Vec4(std::atof(tokens[1].c_str()), std::atof(tokens[2].c_str()), std::atof(tokens[3].c_str()))); normalIndex++; } else if(tokens[0] == "f") { if(tokens.size() < 4) { std::cout << "Invalid face: " << buffer; continue; } int count = countInstanceOf(tokens[1], '/'); std::vector<std::string> subTokens; if(count == 0) { indices.push_back(Vec4(std::atof(tokens[1].c_str()),0,0)); indices.push_back(Vec4(std::atof(tokens[2].c_str()),0,0)); indices.push_back(Vec4(std::atof(tokens[3].c_str()),0,0)); } else if(count == 1) { customTokenize(tokens[1].c_str(), subTokens, '/'); indices.push_back(Vec4(std::atof(subTokens[0].c_str()),std::atof(subTokens[1].c_str()),0)); subTokens.clear(); customTokenize(tokens[2].c_str(), subTokens, '/'); indices.push_back(Vec4(std::atof(subTokens[0].c_str()),std::atof(subTokens[1].c_str()),0)); subTokens.clear(); customTokenize(tokens[3].c_str(), subTokens, '/'); indices.push_back(Vec4(std::atof(subTokens[0].c_str()),std::atof(subTokens[1].c_str()),0)); } else if(count == 2) { } output->indices[faceIndex] = std::atof(tokens[1].c_str())-1; output->indices[faceIndex+1] = std::atof(tokens[2].c_str())-1; output->indices[faceIndex+2] = std::atof(tokens[3].c_str())-1; if (current) { int one = output->indices[faceIndex]; int two = output->indices[faceIndex + 1]; int three = output->indices[faceIndex + 2]; output->vertices[one].Ka = current->Ka; output->vertices[one].Ks = current->Ks; output->vertices[one].Ns = current->Ns; output->vertices[one].color = current->Kd; output->vertices[two].Ka = current->Ka; output->vertices[two].Ks = current->Ks; output->vertices[two].Ns = current->Ns; output->vertices[two].color = current->Kd; output->vertices[three].Ka = current->Ka; output->vertices[three].Ks = current->Ks; output->vertices[three].Ns = current->Ns; output->vertices[three].color = current->Kd; } faceIndex += 3; } else if (tokens[0] == "usemtl") { current = ElysiumEngine::GraphicsSystem::g_GraphicsSystem->getMaterialLibrary().getMaterial(tokens[1]); } } CalculateNormals(output); }
bool TerrainClass::GenerateHeightMap(ID3D11Device* device, bool keydown) { bool result; //the toggle is just a bool that I use to make sure this is only called ONCE when you press a key //until you release the key and start again. We dont want to be generating the terrain 500 //times per second. if(keydown&&(!m_terrainGeneratedToggle)) { int index; float height = 0.0; //MidPoint(); /*for(int j=0; j<m_terrainHeight; j++) { for(int i=0; i<m_terrainWidth; i++) { index = (m_terrainHeight * j) + i; m_heightMap[index].x = (float)i; m_heightMap[index].y= i; m_heightMap[index].z = (float)j; } }*/ //GenerateRandomHeightMap(); //loop through the terrain and set the hieghts how we want. This is where we generate the terrain //in this case I will run a sin-wave through the terrain in one axis. float sinValue = (rand()%12)+1; float cosValue = (((float(rand()%200))/10)-10); float sinMulti = (((float(rand()%100))/10)-5); float cosMulti = (((float(rand()%50))/10)-2.5); if(cosValue == 0) cosValue = 1; for(int j=0; j<m_terrainHeight; j++) { for(int i=0; i<m_terrainWidth; i++) { index = (m_terrainHeight * j) + i; m_heightMap[index].x = (float)i; m_heightMap[index].y+= (float)((sin((float)i/(m_terrainWidth/sinValue))*sinMulti) + (cos((float)j/cosValue)*cosMulti)); //magic numbers ahoy, just to ramp up the height of the sin function so its visible. m_heightMap[index].z = (float)j; } } /* for(int i=0; i<m_terrainWidth; i++) { cosValue = (((float(rand()%200))/10)-10); for(int j=0; j<m_terrainHeight; j++) { index = (m_terrainWidth * i) + j; m_heightMap[index].x = (float)j; m_heightMap[index].y+= (cos((float)j/cosValue)*cosMulti); //magic numbers ahoy, just to ramp up the height of the sin function so its visible. m_heightMap[index].z = (float)i; } }*/ result = CalculateNormals(); if(!result) { return false; } // Initialize the vertex and index buffer that hold the geometry for the terrain. result = InitializeBuffers(device); if(!result) { return false; } m_terrainGeneratedToggle = true; } else { m_terrainGeneratedToggle = false; } return true; }