//! called during the initialization of the entity void TrailEntity::Init() { GraphicComponent* gc = GetComponent<GraphicComponent>(); if (!gc) { gc = snew GraphicComponent(); gc->SetRenderingPass(GraphicComponent::RP_3DTransparent); AddComponent(gc, true); } auto numTriangles = (m_NumEdges - 1) * 2; auto numVertices = numTriangles * 3; auto vb = GraphicsDriver::Instance()->CreateVertexBuffer(); vb->SetName(GetClassName()); vb->SetDynamic(true); vb->SetVertices(snew Vertex3D[numVertices], numVertices, Vertex3D::VF_Pos | Vertex3D::VF_UV | Vertex3D::VF_Color); vb->SetNumVertices(0); vb->SetApplyWorldTransforms(false); gc->SetVertexBuffer(vb); auto startingPos = GetAbsolutePosition(); for (uint i = 0; i < m_NumEdges; ++i) m_Points.push_back(startingPos); super::Init(); }
inline void CD3DXPMeshObject::SetDetailLevel( float fLevel ) { DWORD num_min_verts = m_vecpPMesh[0]->GetMinVertices(); DWORD num_max_verts = m_vecpPMesh.back()->GetMaxVertices(); DWORD num_target_verts = num_min_verts + (DWORD)( (float)(num_max_verts - num_min_verts) * fLevel ); SetNumVertices( num_target_verts ); }
void update_mvertex_network(UVertexNetwork vn, MVertexNetwork& mvn) { assert(vn.vertices == mvn.vertices.get()); assert(vn.cpoints == mvn.cpoints.get()); // mvn.num_vertices = NumVertices(vn); // mvn.num_cpoints = NumCPoints(vn); SetNumVertices(NumVertices(vn), &mvn); SetNumCPoints(NumCPoints(vn), &mvn); }
NAMESPACE_OCT_BEGIN MVertexNetwork make_mvertex_network() { MVertexNetwork mvn; mvn.header.reset(new int[2]); SetNumVertices(0, &mvn); mvn.vertex_array_capacity = 64; mvn.vertices = shared_array<Vertex>(new Vertex[64]); SetNumCPoints(0, &mvn); mvn.cpoint_array_capacity = 0; mvn.cpoints = shared_array<GeomPoint>(); UVertexNetwork uvn = make_vertex_network(mvn); Initialize(&uvn); update_mvertex_network(uvn, mvn); return mvn; }
MS3Dmodel::MS3Dmodel(char * filename) { //Initialize textures handles array m_hTex = NULL; //Stage 1: Read binary file into temporary structures in main memory ms3d_header header; word NumVertices; ms3d_vertex *pvert; word NumTriangles; ms3d_triangle *ptri; word NumGroups; ms3d_group *pgrp; word NumMaterials; ms3d_material *pmat; GLuint i, j; const int tmpstrsize = 150; char tmpstr[tmpstrsize]; std::fstream file; file.open(filename, std::fstream::in | std::fstream::binary); if (file.is_open()) { //Due to strange alignment issues (header structure should have a sizeof 14 but is 16) each member will be read separately //Read header file.read((char*)(&header.id), 10 * sizeof(char)); file.read((char*)(&header.version), sizeof(int)); //Read number of vertices file.read((char*)(&NumVertices), sizeof(word)); //Allocate space for vertices information pvert = new ms3d_vertex[NumVertices]; //Read vertex information for (i = 0; i<NumVertices; i++) { file.read((char*)&pvert[i].flags, sizeof(byte)); file.read((char*)&pvert[i].vertex, 3 * sizeof(float)); file.read((char*)&pvert[i].boneId, sizeof(char)); file.read((char*)&pvert[i].referenceCount, sizeof(byte)); } //Read number of triangles file.read((char*)(&NumTriangles), sizeof(word)); //Allocate space for triangles information ptri = new ms3d_triangle[NumTriangles]; //Read triangle information for (i = 0; i<NumTriangles; i++) { file.read((char*)&ptri[i].flags, sizeof(word)); file.read((char*)&ptri[i].vertexIndices, 3 * sizeof(word)); file.read((char*)&ptri[i].vertexNormals, 9 * sizeof(float)); file.read((char*)&ptri[i].s, 3 * sizeof(float)); file.read((char*)&ptri[i].t, 3 * sizeof(float)); file.read((char*)&ptri[i].smoothingGroup, sizeof(byte)); file.read((char*)&ptri[i].groupIndex, sizeof(byte)); } //Read number of groups file.read((char*)(&NumGroups), sizeof(word)); //Allocate space for groups information pgrp = new ms3d_group[NumGroups]; //Read group information for (i = 0; i<NumGroups; i++) { file.read((char*)&pgrp[i].flags, sizeof(byte)); file.read((char*)&pgrp[i].name, 32 * sizeof(char)); file.read((char*)&pgrp[i].numtriangles, sizeof(word)); pgrp[i].triangleIndices = new word[pgrp[i].numtriangles]; for (j = 0; j<pgrp[i].numtriangles; j++) { file.read((char*)&pgrp[i].triangleIndices[j], sizeof(word)); } file.read((char*)&pgrp[i].materialIndex, sizeof(char)); } //Read number of materials file.read((char*)(&NumMaterials), sizeof(word)); //Allocate space for material information pmat = new ms3d_material[NumMaterials]; //Read material information for (i = 0; i<NumMaterials; i++) { file.read((char*)&pmat[i].name, 32 * sizeof(char)); file.read((char*)&pmat[i].ambient, 4 * sizeof(float)); file.read((char*)&pmat[i].diffuse, 4 * sizeof(float)); file.read((char*)&pmat[i].specular, 4 * sizeof(float)); file.read((char*)&pmat[i].emissive, 4 * sizeof(float)); file.read((char*)&pmat[i].shininess, sizeof(float)); file.read((char*)&pmat[i].transparency, sizeof(float)); file.read((char*)&pmat[i].mode, sizeof(char)); file.read((char*)&pmat[i].texture, 128 * sizeof(char)); file.read((char*)&pmat[i].alphamap, 128 * sizeof(char)); } //Close model file file.close(); SetNumVertices(NumTriangles * 3); for (i = 0; i<NumTriangles; i++) { m_pVertices[3 * i + 0].Pos.x = pvert[ptri[i].vertexIndices[0]].vertex[0]; m_pVertices[3 * i + 0].Pos.y = pvert[ptri[i].vertexIndices[0]].vertex[1]; m_pVertices[3 * i + 0].Pos.z = pvert[ptri[i].vertexIndices[0]].vertex[2]; m_pVertices[3 * i + 0].Pos.w = 1.0f; m_pVertices[3 * i + 1].Pos.x = pvert[ptri[i].vertexIndices[1]].vertex[0]; m_pVertices[3 * i + 1].Pos.y = pvert[ptri[i].vertexIndices[1]].vertex[1]; m_pVertices[3 * i + 1].Pos.z = pvert[ptri[i].vertexIndices[1]].vertex[2]; m_pVertices[3 * i + 1].Pos.w = 1.0f; m_pVertices[3 * i + 2].Pos.x = pvert[ptri[i].vertexIndices[2]].vertex[0]; m_pVertices[3 * i + 2].Pos.y = pvert[ptri[i].vertexIndices[2]].vertex[1]; m_pVertices[3 * i + 2].Pos.z = pvert[ptri[i].vertexIndices[2]].vertex[2]; m_pVertices[3 * i + 2].Pos.w = 1.0f; m_pVertices[3 * i + 0].Norm.x = ptri[i].vertexNormals[0][0]; m_pVertices[3 * i + 0].Norm.y = ptri[i].vertexNormals[0][1]; m_pVertices[3 * i + 0].Norm.z = ptri[i].vertexNormals[0][2]; m_pVertices[3 * i + 0].Norm.w = 0.0f; m_pVertices[3 * i + 1].Norm.x = ptri[i].vertexNormals[1][0]; m_pVertices[3 * i + 1].Norm.y = ptri[i].vertexNormals[1][1]; m_pVertices[3 * i + 1].Norm.z = ptri[i].vertexNormals[1][2]; m_pVertices[3 * i + 1].Norm.w = 0.0f; m_pVertices[3 * i + 2].Norm.x = ptri[i].vertexNormals[2][0]; m_pVertices[3 * i + 2].Norm.y = ptri[i].vertexNormals[2][1]; m_pVertices[3 * i + 2].Norm.z = ptri[i].vertexNormals[2][2]; m_pVertices[3 * i + 2].Norm.w = 0.0f; m_pVertices[3 * i + 0].Tex.x = ptri[i].s[0]; m_pVertices[3 * i + 0].Tex.y = ptri[i].t[0]; m_pVertices[3 * i + 0].Tex.z = 0.0f; m_pVertices[3 * i + 0].Tex.w = 1.0f; m_pVertices[3 * i + 1].Tex.x = ptri[i].s[1]; m_pVertices[3 * i + 1].Tex.y = ptri[i].t[1]; m_pVertices[3 * i + 1].Tex.z = 0.0f; m_pVertices[3 * i + 1].Tex.w = 1.0f; m_pVertices[3 * i + 2].Tex.x = ptri[i].s[2]; m_pVertices[3 * i + 2].Tex.y = ptri[i].t[2]; m_pVertices[3 * i + 2].Tex.z = 0.0f; m_pVertices[3 * i + 2].Tex.w = 1.0f; } GenerateVertexBuffer(); SetNumSubsets(NumGroups); m_hTex = new GLuint[m_uiNumSubsets]; for (i = 0; i<m_uiNumSubsets; i++) { ResizeSubset(i, pgrp[i].numtriangles); for (j = 0; j<4; j++) { m_pSubsets[i].Material.Ambient[j] = pmat[pgrp[i].materialIndex].ambient[j]; m_pSubsets[i].Material.Diffuse[j] = pmat[pgrp[i].materialIndex].diffuse[j]; m_pSubsets[i].Material.Emissive[j] = pmat[pgrp[i].materialIndex].emissive[j]; m_pSubsets[i].Material.Specular[j] = pmat[pgrp[i].materialIndex].specular[j]; } if (pmat[pgrp[i].materialIndex].shininess != 0.0f) { m_pSubsets[i].Material.Shininess[0] = pmat[pgrp[i].materialIndex].shininess; } else { m_pSubsets[i].Material.Shininess[0] = 1.0f; } sprintf_s(tmpstr, tmpstrsize, "Textures\\%s", &pmat[pgrp[i].materialIndex].texture); m_hTex[i] = SOIL_load_OGL_texture(tmpstr, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_POWER_OF_TWO); for (j = 0; j<pgrp[i].numtriangles; j++) { m_pSubsets[i].pIndices[3 * j] = 3 * (pgrp[i].triangleIndices[j]); m_pSubsets[i].pIndices[3 * j + 1] = (3 * (pgrp[i].triangleIndices[j])) + 1; m_pSubsets[i].pIndices[3 * j + 2] = (3 * (pgrp[i].triangleIndices[j])) + 2; } GenerateSubsetIndicesBuffer(i); } delete[] pvert; delete[] ptri; delete[] pgrp; delete[] pmat; } }
//! called during the update of the entity void TrailEntity::Update() { const auto& pos = GetAbsolutePosition(); auto vb = GetComponent<GraphicComponent>()->GetVertexBuffer(); vb->SetNumVertices(0); // update points for (size_t i = 0; i < m_Points.size(); ++i) { auto& point = m_Points[i]; auto factor = (float)i / (m_Points.size() - 1); auto duration = Math::Lerp(0.0f, m_TrailDuration, factor); point = Math::Damp(point, pos, g_fDeltaTime, duration); } // discard points that are too close to each other auto thresholdSQ = m_Treshold*m_Treshold; std::vector<Vector3> points; points.push_back(m_Points[0]); for (int i = 0; i < (int)m_Points.size()-1; ++i) { auto& point1 = m_Points[i]; auto& point2 = m_Points[i+1]; auto distSQ = (point1 - point2).GetLengthSquared(); if (distSQ < thresholdSQ) continue; points.push_back(point2); } if (points.size() > 1) { auto vertices = reinterpret_cast<Vertex3D*>(vb->GetVertices()); uint vtx = 0; auto texU = 0.0f; auto step = 1.0f / (points.size() - 1); auto factor = 1.0f; auto alphaFactor = 1.0f; for (int i = 0; i < (int)points.size() - 1; ++i) { const auto& v1 = points[i]; const auto& v2 = points[i + 1]; const auto& dir1 = (v2 - v1).Normalized(); Vector3 dir2; auto afterNext = i+2; if (afterNext < (int)points.size()) dir2 = (points[afterNext] - v2).Normalized(); else dir2 = dir1; auto thickness1 = m_Thickness*factor; auto thickness2 = m_Thickness*(factor - step); auto vLateralAxe1 = dir1.CrossProduct(Vector3::Up)*thickness1; auto vLateralAxe2 = dir2.CrossProduct(Vector3::Up)*thickness2; vertices[vtx + 0].UV = Vector2::Create(texU, 0.0f); vertices[vtx + 0].Pos = v1 + vLateralAxe1; vertices[vtx + 1].UV = Vector2::Create(texU, 1.0f); vertices[vtx + 1].Pos = v1 - vLateralAxe1; vertices[vtx + 2].UV = Vector2::Create(texU + m_UPerSegment, 0.0f); vertices[vtx + 2].Pos = v2 + vLateralAxe2; vertices[vtx + 3].UV = Vector2::Create(texU + m_UPerSegment, 0.0f); vertices[vtx + 3].Pos = v2 + vLateralAxe2; vertices[vtx + 4].UV = Vector2::Create(texU, 1.0f); vertices[vtx + 4].Pos = v1 - vLateralAxe1; vertices[vtx + 5].UV = Vector2::Create(texU + m_UPerSegment, 1.0f); vertices[vtx + 5].Pos = v2 - vLateralAxe2; // update alpha auto alpha1 = alphaFactor; auto alpha2 = alphaFactor - (step * m_FadeFactor); auto color1 = Color::Create(Color::White.RGB, Math::Clamp(alpha1, 0.0f, alpha1)); auto color2 = Color::Create(Color::White.RGB, Math::Clamp(alpha2, 0.0f, alpha2)); vertices[vtx + 0].color = color1; vertices[vtx + 1].color = color1; vertices[vtx + 2].color = color2; vertices[vtx + 3].color = color2; vertices[vtx + 4].color = color1; vertices[vtx + 5].color = color2; vtx += 6; texU += m_UPerSegment; factor -= step; alphaFactor -= (step * m_FadeFactor); } vb->SetNumVertices(vtx); vb->SetDirty(true); } }