void Image(const Texture& texture, const Vector2f& size, const Rectf& textureRect, const Color& tintColor, const Color& borderColor) { Vector2f textureSize = static_cast<Vector2f>(texture.getSize()); ImVec2 uv0(textureRect.left / textureSize.x, textureRect.top / textureSize.y); ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x, (textureRect.top + textureRect.height) / textureSize.y); ImGui::Image((void*)texture.getNativeHandle(), size, uv0, uv1, tintColor, borderColor); }
ManualObject* OgreNewtonMesh::CreateEntity (const String& name) const { ManualObject* const object = new ManualObject(name); int pointCount = GetPointCount(); int indexCount = GetTotalIndexCount(); dNewtonScopeBuffer<int> indexList (indexCount); dNewtonScopeBuffer<int> remapIndex (indexCount); dNewtonScopeBuffer<dNewtonMesh::dPoint> posits (pointCount); dNewtonScopeBuffer<dNewtonMesh::dPoint> normals (pointCount); dNewtonScopeBuffer<dNewtonMesh::dUV> uv0 (pointCount); dNewtonScopeBuffer<dNewtonMesh::dUV> uv1 (pointCount); GetVertexStreams(&posits[0], &normals[0], &uv0[0], &uv1[0]); void* const materialsHandle = BeginMaterialHandle (); for (int handle = GetMaterialIndex (materialsHandle); handle != -1; handle = GetNextMaterialIndex (materialsHandle, handle)) { int materialIndex = MaterialGetMaterial (materialsHandle, handle); int indexCount = MaterialGetIndexCount (materialsHandle, handle); MaterialGetIndexStream (materialsHandle, handle, &indexList[0]); MaterialMap::const_iterator materialItr = m_materialMap.find(materialIndex); //object->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST); object->begin(materialItr->second->getName(), Ogre::RenderOperation::OT_TRIANGLE_LIST); // ogre does not support shared vertex for sub mesh, we will have remap the vertex data int vertexCount = 0; memset (&remapIndex[0], 0xff, indexCount * sizeof (remapIndex[0])); for( int i = 0; i < indexCount; i ++) { int index = indexList[i]; if (remapIndex[index] == -1) { remapIndex[index] = vertexCount; object->position (posits[index].m_x, posits[index].m_y, posits[index].m_z); object->normal (normals[index].m_x, normals[index].m_y, normals[index].m_z); object->textureCoord (uv0[index].m_u, uv0[index].m_v); vertexCount ++; } indexList[i] = remapIndex[index]; } for (int i = 0; i < indexCount; i += 3) { object->triangle (indexList[i + 0], indexList[i + 1], indexList[i + 2]); } object->end(); } EndMaterialHandle (materialsHandle); return object; }
void Triangle::build() { //Dessin 2D //glm::vec3 pos0(-1.0f, -1.0f, 0.0f); glm::vec3 pos0(-1.f, -1.f, 0.0f); glm::vec3 norm0(0.f, 0.f, 1.0f); glm::vec2 uv0(0.f, 0.f); //glm::vec3 pos1(1.0f, -1.0f, 0.0f); glm::vec3 pos1(3.f, -1.f, 0.0f); glm::vec3 norm1(0.f, 0.f, 1.0f); glm::vec2 uv1(2.f, 0.f); //glm::vec3 pos2(0.f, 0.5f, 0.0f); glm::vec3 pos2(-1.f, 3.0f, 0.0f); glm::vec3 norm2(0.f, 0.f, 1.0f); glm::vec2 uv2(0.f, 2.f); /* Pour un triangle faisant tout l'écran -1.0 -1.0 0.000000 1.0 -1.0 0.000000 0.0 0.5 0.000000 */ _vertices[0].position = pos0; _vertices[0].normal = norm0; _vertices[0].uv = uv0; _vertices[1].position = pos1; _vertices[1].normal = norm1; _vertices[1].uv = uv1; _vertices[2].position = pos2; _vertices[2].normal = norm2; _vertices[2].uv = uv2; _indices[0] = 0; _indices[1] = 1; _indices[2] = 2; }
void GSVertexTrace::FindMinMax(const void* vertex, const uint32* index, int count) { const GSDrawingContext* context = m_state->m_context; int n = 1; switch(primclass) { case GS_POINT_CLASS: n = 1; break; case GS_LINE_CLASS: case GS_SPRITE_CLASS: n = 2; break; case GS_TRIANGLE_CLASS: n = 3; break; } GSVector4 tmin = s_minmax.xxxx(); GSVector4 tmax = s_minmax.yyyy(); GSVector4i cmin = GSVector4i::xffffffff(); GSVector4i cmax = GSVector4i::zero(); #if _M_SSE >= 0x401 GSVector4i pmin = GSVector4i::xffffffff(); GSVector4i pmax = GSVector4i::zero(); #else GSVector4 pmin = s_minmax.xxxx(); GSVector4 pmax = s_minmax.yyyy(); #endif const GSVertex* RESTRICT v = (GSVertex*)vertex; for(int i = 0; i < count; i += n) { if(primclass == GS_POINT_CLASS) { GSVector4i c(v[index[i]].m[0]); if(color) { cmin = cmin.min_u8(c); cmax = cmax.max_u8(c); } if(tme) { if(!fst) { GSVector4 stq = GSVector4::cast(c); GSVector4 q = stq.wwww(); stq = (stq.xyww() * q.rcpnr()).xyww(q); tmin = tmin.min(stq); tmax = tmax.max(stq); } else { GSVector4i uv(v[index[i]].m[1]); GSVector4 st = GSVector4(uv.uph16()).xyxy(); tmin = tmin.min(st); tmax = tmax.max(st); } } GSVector4i xyzf(v[index[i]].m[1]); GSVector4i xy = xyzf.upl16(); GSVector4i z = xyzf.yyyy(); #if _M_SSE >= 0x401 GSVector4i p = xy.blend16<0xf0>(z.uph32(xyzf)); pmin = pmin.min_u32(p); pmax = pmax.max_u32(p); #else GSVector4 p = GSVector4(xy.upl64(z.srl32(1).upl32(xyzf.wwww()))); pmin = pmin.min(p); pmax = pmax.max(p); #endif } else if(primclass == GS_LINE_CLASS) { GSVector4i c0(v[index[i + 0]].m[0]); GSVector4i c1(v[index[i + 1]].m[0]); if(color) { if(iip) { cmin = cmin.min_u8(c0.min_u8(c1)); cmax = cmax.max_u8(c0.max_u8(c1)); } else { cmin = cmin.min_u8(c1); cmax = cmax.max_u8(c1); } } if(tme) { if(!fst) { GSVector4 stq0 = GSVector4::cast(c0); GSVector4 stq1 = GSVector4::cast(c1); GSVector4 q = stq0.wwww(stq1).rcpnr(); stq0 = (stq0.xyww() * q.xxxx()).xyww(stq0); stq1 = (stq1.xyww() * q.zzzz()).xyww(stq1); tmin = tmin.min(stq0.min(stq1)); tmax = tmax.max(stq0.max(stq1)); } else { GSVector4i uv0(v[index[i + 0]].m[1]); GSVector4i uv1(v[index[i + 1]].m[1]); GSVector4 st0 = GSVector4(uv0.uph16()).xyxy(); GSVector4 st1 = GSVector4(uv1.uph16()).xyxy(); tmin = tmin.min(st0.min(st1)); tmax = tmax.max(st0.max(st1)); } } GSVector4i xyzf0(v[index[i + 0]].m[1]); GSVector4i xyzf1(v[index[i + 1]].m[1]); GSVector4i xy0 = xyzf0.upl16(); GSVector4i z0 = xyzf0.yyyy(); GSVector4i xy1 = xyzf1.upl16(); GSVector4i z1 = xyzf1.yyyy(); #if _M_SSE >= 0x401 GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf0)); GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1)); pmin = pmin.min_u32(p0.min_u32(p1)); pmax = pmax.max_u32(p0.max_u32(p1)); #else GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf0.wwww()))); GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww()))); pmin = pmin.min(p0.min(p1)); pmax = pmax.max(p0.max(p1)); #endif } else if(primclass == GS_TRIANGLE_CLASS) { GSVector4i c0(v[index[i + 0]].m[0]); GSVector4i c1(v[index[i + 1]].m[0]); GSVector4i c2(v[index[i + 2]].m[0]); if(color) { if(iip) { cmin = cmin.min_u8(c2).min_u8(c0.min_u8(c1)); cmax = cmax.max_u8(c2).max_u8(c0.max_u8(c1)); } else { cmin = cmin.min_u8(c2); cmax = cmax.max_u8(c2); } } if(tme) { if(!fst) { GSVector4 stq0 = GSVector4::cast(c0); GSVector4 stq1 = GSVector4::cast(c1); GSVector4 stq2 = GSVector4::cast(c2); GSVector4 q = stq0.wwww(stq1).xzww(stq2).rcpnr(); stq0 = (stq0.xyww() * q.xxxx()).xyww(stq0); stq1 = (stq1.xyww() * q.yyyy()).xyww(stq1); stq2 = (stq2.xyww() * q.zzzz()).xyww(stq2); tmin = tmin.min(stq2).min(stq0.min(stq1)); tmax = tmax.max(stq2).max(stq0.max(stq1)); } else { GSVector4i uv0(v[index[i + 0]].m[1]); GSVector4i uv1(v[index[i + 1]].m[1]); GSVector4i uv2(v[index[i + 2]].m[1]); GSVector4 st0 = GSVector4(uv0.uph16()).xyxy(); GSVector4 st1 = GSVector4(uv1.uph16()).xyxy(); GSVector4 st2 = GSVector4(uv2.uph16()).xyxy(); tmin = tmin.min(st2).min(st0.min(st1)); tmax = tmax.max(st2).max(st0.max(st1)); } } GSVector4i xyzf0(v[index[i + 0]].m[1]); GSVector4i xyzf1(v[index[i + 1]].m[1]); GSVector4i xyzf2(v[index[i + 2]].m[1]); GSVector4i xy0 = xyzf0.upl16(); GSVector4i z0 = xyzf0.yyyy(); GSVector4i xy1 = xyzf1.upl16(); GSVector4i z1 = xyzf1.yyyy(); GSVector4i xy2 = xyzf2.upl16(); GSVector4i z2 = xyzf2.yyyy(); #if _M_SSE >= 0x401 GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf0)); GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1)); GSVector4i p2 = xy2.blend16<0xf0>(z2.uph32(xyzf2)); pmin = pmin.min_u32(p2).min_u32(p0.min_u32(p1)); pmax = pmax.max_u32(p2).max_u32(p0.max_u32(p1)); #else GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf0.wwww()))); GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww()))); GSVector4 p2 = GSVector4(xy2.upl64(z2.srl32(1).upl32(xyzf2.wwww()))); pmin = pmin.min(p2).min(p0.min(p1)); pmax = pmax.max(p2).max(p0.max(p1)); #endif } else if(primclass == GS_SPRITE_CLASS) { GSVector4i c0(v[index[i + 0]].m[0]); GSVector4i c1(v[index[i + 1]].m[0]); if(color) { if(iip) { cmin = cmin.min_u8(c0.min_u8(c1)); cmax = cmax.max_u8(c0.max_u8(c1)); } else { cmin = cmin.min_u8(c1); cmax = cmax.max_u8(c1); } } if(tme) { if(!fst) { GSVector4 stq0 = GSVector4::cast(c0); GSVector4 stq1 = GSVector4::cast(c1); GSVector4 q = stq1.wwww().rcpnr(); stq0 = (stq0.xyww() * q).xyww(stq1); stq1 = (stq1.xyww() * q).xyww(stq1); tmin = tmin.min(stq0.min(stq1)); tmax = tmax.max(stq0.max(stq1)); } else { GSVector4i uv0(v[index[i + 0]].m[1]); GSVector4i uv1(v[index[i + 1]].m[1]); GSVector4 st0 = GSVector4(uv0.uph16()).xyxy(); GSVector4 st1 = GSVector4(uv1.uph16()).xyxy(); tmin = tmin.min(st0.min(st1)); tmax = tmax.max(st0.max(st1)); } } GSVector4i xyzf0(v[index[i + 0]].m[1]); GSVector4i xyzf1(v[index[i + 1]].m[1]); GSVector4i xy0 = xyzf0.upl16(); GSVector4i z0 = xyzf0.yyyy(); GSVector4i xy1 = xyzf1.upl16(); GSVector4i z1 = xyzf1.yyyy(); #if _M_SSE >= 0x401 GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf1)); GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1)); pmin = pmin.min_u32(p0.min_u32(p1)); pmax = pmax.max_u32(p0.max_u32(p1)); #else GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf1.wwww()))); GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww()))); pmin = pmin.min(p0.min(p1)); pmax = pmax.max(p0.max(p1)); #endif } } #if _M_SSE >= 0x401 pmin = pmin.blend16<0x30>(pmin.srl32(1)); pmax = pmax.blend16<0x30>(pmax.srl32(1)); #endif GSVector4 o(context->XYOFFSET); GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f); m_min.p = (GSVector4(pmin) - o) * s; m_max.p = (GSVector4(pmax) - o) * s; if(tme) { if(fst) { s = GSVector4(1.0f / 16, 1.0f).xxyy(); } else { s = GSVector4(1 << context->TEX0.TW, 1 << context->TEX0.TH, 1, 1); } m_min.t = tmin * s; m_max.t = tmax * s; } else { m_min.t = GSVector4::zero(); m_max.t = GSVector4::zero(); } if(color) { m_min.c = cmin.zzzz().u8to32(); m_max.c = cmax.zzzz().u8to32(); } else { m_min.c = GSVector4i::zero(); m_max.c = GSVector4i::zero(); } }
void DrawCharRect(Vector2 p0, Vector2 p1, int sprite, int flags, Colour colour) { if ((gRectVertCount + 6) > kMaxRectVerts) { DebugLn("DrawRect overflow"); return; } Vertex* v = &gRectVerts[gRectVertCount]; gRectVertCount += 6; int sx = sprite & 0x1F; int sy = sprite >> 5; Vector2 uv0(sx / 32.0f, sy / 32.0f); Vector2 uv1((sx + 1) / 32.0f, (sy + 1) / 32.0f); Vector2 scale(2.0f / (float)kWinWidth, -2.0f / (float)kWinHeight); if (flags & kFlipX) Swap(uv0.x, uv1.x); if (flags & kFlipY) Swap(uv0.y, uv1.y); // t0 v->pos.x = p0.x * scale.x; v->pos.y = p0.y * scale.y; v->uv.x = uv0.x; v->uv.y = uv0.y; v->colour = colour; v++; v->pos.x = p1.x * scale.x; v->pos.y = p0.y * scale.y; v->uv.x = uv1.x; v->uv.y = uv0.y; v->colour = colour; v++; v->pos.x = p1.x * scale.x; v->pos.y = p1.y * scale.y; v->uv.x = uv1.x; v->uv.y = uv1.y; v->colour = colour; v++; // t1 v->pos.x = p0.x * scale.x; v->pos.y = p0.y * scale.y; v->uv.x = uv0.x; v->uv.y = uv0.y; v->colour = colour; v++; v->pos.x = p1.x * scale.x; v->pos.y = p1.y * scale.y; v->uv.x = uv1.x; v->uv.y = uv1.y; v->colour = colour; v++; v->pos.x = p0.x * scale.x; v->pos.y = p1.y * scale.y; v->uv.x = uv0.x; v->uv.y = uv1.y; v->colour = colour; }
void compute_tangent_vectors(mesh_t &mesh) { int vertex_count = mesh.vertices.size() / 3; int face_count = mesh.indices.size() / 3; std::vector<glm::vec3> tangents; tangents.resize(vertex_count); int *tangent_counts = new int[vertex_count]; for (int i = 0; i < vertex_count; i++) tangent_counts[i] = 0; std::vector<float> &vertices = mesh.vertices; std::vector<float> &normals = mesh.normals; std::vector<float> &tex_coords = mesh.tex_coords; std::vector<unsigned int> &indices = mesh.indices; for (int i = 0; i < face_count; i++) { int i0 = indices[3*i]; int i1 = indices[3*i + 1]; int i2 = indices[3*i + 2]; int j0 = 2*i0; int j1 = 2*i1; int j2 = 2*i2; glm::vec2 uv0(tex_coords[j0], tex_coords[j0 + 1]); glm::vec2 uv1(tex_coords[j1], tex_coords[j1 + 1]); glm::vec2 uv2(tex_coords[j2], tex_coords[j2 + 1]); glm::vec2 st1 = uv1 - uv0; glm::vec2 st2 = uv2 - uv0; float det = st1.x*st2.y - st2.x*st1.y; if (det == 0.0f) continue; // pass if inverse matrix does not exist // assert(det != 0.0f); int k0 = 3*i0; int k1 = 3*i1; int k2 = 3*i2; glm::vec3 p0(vertices[k0], vertices[k0 + 1], vertices[k0 + 2]); glm::vec3 p1(vertices[k1], vertices[k1 + 1], vertices[k1 + 2]); glm::vec3 p2(vertices[k2], vertices[k2 + 1], vertices[k2 + 2]); glm::vec3 q1 = p1 - p0; glm::vec3 q2 = p2 - p0; float coef = 1.0f / det; glm::mat3 m( q1.x, q2.x, 0.0f, q1.y, q2.y, 0.0f, q1.z, q2.z, 0.0f ); glm::vec3 t = coef * glm::vec3(st2.y, -st1.y, 0.0f) * m; tangents[i0] += t; tangents[i1] += t; tangents[i2] += t; tangent_counts[i0]++; tangent_counts[i1]++; tangent_counts[i2]++; } mesh.tangents.resize(3*vertex_count); for (int i = 0; i < vertex_count; i++) { const glm::vec3 n(normals[3*i], normals[3*i + 1], normals[3*i + 2]); const glm::vec3 t = tangent_counts[i] > 0 ? tangents[i] / (float)tangent_counts[i] : tangents[i]; tangents[i] = glm::normalize(t - glm::dot(n, t) * n); mesh.tangents[3*i] = tangents[i].x; mesh.tangents[3*i + 1] = tangents[i].y; mesh.tangents[3*i + 2] = tangents[i].z; } delete [] tangent_counts; }
// // MQO // 面倒なので四角ポリゴンはないものと仮定 // void build_from_mqo( mqo_reader::document_type& doc, float scale, DWORD color, TextureCache& tc ) { clear(); // マテリアル for( mqo_reader::materials_type::const_iterator i = doc.materials.begin() ; i != doc.materials.end() ; ++i ) { SubModel m; m.vb = NULL; m.ib = NULL; m.texture = NULL; if( (*i).texture != "" ) { m.texture = tc.get_texture( (*i).texture ); } submodels_.push_back( m ); } { // default material SubModel m; m.vb = NULL; m.ib = NULL; submodels_.push_back( m ); } // 頂点, 面 for( mqo_reader::objdic_type::const_iterator i = doc.objects.begin() ; i != doc.objects.end() ; ++i ) { const mqo_reader::object_type& obj = (*i).second; // dictionary: // ( source vertex index, uv ) => destination vertex index struct VertexKey { int index; D3DXVECTOR2 uv; VertexKey(){} VertexKey( int aindex, const D3DXVECTOR2& auv ) : index( aindex ), uv( auv ) { } bool operator<( const VertexKey& a ) const { if( index < a.index ) { return true; } if( a.index < index ) { return false; } if( uv.x < a.uv.x ) { return true; } if( a.uv.x < uv.x ) { return false; } return uv.y < a.uv.y; } }; std::vector< std::map< VertexKey, int > > used_vertices; used_vertices.resize( submodels_.size() ); // マテリアルごとに使用頂点を分類 for( mqo_reader::faces_type::const_iterator j = obj.faces.begin() ; j != obj.faces.end() ; ++j ) { const mqo_reader::face_type& face = *j; int material_index = face.material_index; if( material_index == -1 ) { material_index = int( submodels_.size() - 1 ); } int i0 = face.vertex_indices[0]; int i1 = face.vertex_indices[1]; int i2 = face.vertex_indices[2]; D3DXVECTOR2 uv0( face.uv[0].u, face.uv[0].v ); D3DXVECTOR2 uv1( face.uv[1].u, face.uv[1].v ); D3DXVECTOR2 uv2( face.uv[2].u, face.uv[2].v ); std::map< VertexKey, int >& c = used_vertices[material_index]; c[ VertexKey( i0, uv0 ) ] = -1 ; c[ VertexKey( i1, uv1 ) ] = -1 ; c[ VertexKey( i2, uv2 ) ] = -1 ; } // マテリアルごとに使われている頂点を追加 size_t n = submodels_.size(); for( size_t i = 0 ; i < n ; i++ ) { SubModel& m = submodels_[i]; std::map< VertexKey, int >& c = used_vertices[i]; int no = int( m.vertex_source.size() ); for( std::map< VertexKey, int >::iterator j = c.begin(); j != c.end() ; ++j ) { const mqo_reader::vertex_type& src = obj.vertices[(*j).first.index]; model_vertex_type dst; dst.position = D3DXVECTOR3( src.x * scale, src.y * scale, src.z * -scale ); dst.normal = D3DXVECTOR3( 0, 0, 0 ); dst.diffuse = color; dst.uv = (*j).first.uv; m.vertex_source.push_back( dst ); (*j).second = no++; } } // マテリアルごとに面を追加 for( mqo_reader::faces_type::const_iterator j = obj.faces.begin() ; j != obj.faces.end() ; ++j ) { const mqo_reader::face_type& face = *j; int material_index = face.material_index; if( material_index == -1 ) { material_index = int( submodels_.size() - 1 ); } int i0 = face.vertex_indices[0]; int i1 = face.vertex_indices[1]; int i2 = face.vertex_indices[2]; D3DXVECTOR2 uv0( face.uv[0].u, face.uv[0].v ); D3DXVECTOR2 uv1( face.uv[1].u, face.uv[1].v ); D3DXVECTOR2 uv2( face.uv[2].u, face.uv[2].v ); std::map< VertexKey, int >& c = used_vertices[material_index]; int k0 = c[VertexKey( i0, uv0 )]; int k1 = c[VertexKey( i1, uv1 )]; int k2 = c[VertexKey( i2, uv2 )]; SubModel& m = submodels_[material_index]; m.index_source.push_back( k0 ); m.index_source.push_back( k1 ); m.index_source.push_back( k2 ); model_vertex_type& v0 = m.vertex_source[ k0 ]; model_vertex_type& v1 = m.vertex_source[ k1 ]; model_vertex_type& v2 = m.vertex_source[ k2 ]; D3DXVECTOR3 normal = cross( v1.position - v0.position, v2.position - v0.position ); v0.normal += normal; v1.normal += normal; v2.normal += normal; } } // 法線後処理 size_t n = submodels_.size(); for( size_t j = 0 ; j < n ; j++ ) { SubModel& m = submodels_[j]; for( std::vector< model_vertex_type >::iterator i = m.vertex_source.begin() ; i != m.vertex_source.end() ; ++i ) { D3DXVec3Normalize( &(*i).normal, &(*i).normal ); } } build_submodels(); }
void CoronaRenderer::defineMesh(mtco_MayaObject *obj) { MObject meshObject = obj->mobject; MStatus stat = MStatus::kSuccess; bool hasDisplacement = false; Corona::Abstract::Map *displacementMap = NULL; float displacementMin = 0.0f; float displacementMax = 0.01f; // I do it here for displacement mapping, maybe we should to another place getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups); if( obj->shadingGroups.length() > 0) { MFnDependencyNode shadingGroup(obj->shadingGroups[0]); MString sgn = shadingGroup.name(); MObject displacementObj = getConnectedInNode(obj->shadingGroups[0], "displacementShader"); MString doo = getObjectName(displacementObj); if( (displacementObj != MObject::kNullObj) && (displacementObj.hasFn(MFn::kDisplacementShader))) { MObject displacementMapObj = getConnectedInNode(displacementObj, "displacement"); if( (displacementMapObj != MObject::kNullObj) && (displacementMapObj.hasFn(MFn::kFileTexture))) { MFnDependencyNode displacmentMapNode(displacementObj); getFloat("mtco_displacementMin", displacmentMapNode, displacementMin); getFloat("mtco_displacementMax", displacmentMapNode, displacementMax); MString fileTexturePath = getConnectedFileTexturePath(MString("displacement"), displacmentMapNode); if( fileTexturePath != "") { MapLoader loader; displacementMap = loader.loadBitmap(fileTexturePath.asChar()); hasDisplacement = true; } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; meshFn.getPoints(points); MFloatVectorArray normals; meshFn.getNormals( normals, MSpace::kWorld ); MFloatArray uArray, vArray; meshFn.getUVs(uArray, vArray); //logger.debug(MString("Translating mesh object ") + meshFn.name().asChar()); MString meshFullName = makeGoodString(meshFn.fullPathName()); Corona::TriangleData td; Corona::IGeometryGroup* geom = NULL; geom = this->context.scene->addGeomGroup(); obj->geom = geom; for( uint vtxId = 0; vtxId < points.length(); vtxId++) { geom->getVertices().push(Corona::Pos(points[vtxId].x,points[vtxId].y,points[vtxId].z)); } for( uint nId = 0; nId < normals.length(); nId++) { geom->getNormals().push(Corona::Dir(normals[nId].x,normals[nId].y,normals[nId].z)); } for( uint tId = 0; tId < uArray.length(); tId++) { geom->getMapCoords().push(Corona::Pos(uArray[tId],vArray[tId],0.0f)); geom->getMapCoordIndices().push(geom->getMapCoordIndices().size()); } MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; for(faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); MIntArray faceUVIndices; faceNormalIds.clear(); for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; faceIt.getUVIndex(vtxId, uvIndex); faceUVIndices.append(uvIndex); } for( int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for( uint triVtxId = 0; triVtxId < 3; triVtxId++) { for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; if( hasDisplacement ) { Corona::DisplacedTriangleData tri; tri.displacement.map = displacementMap; MPoint p0 = points[vtxId0]; MPoint p1 = points[vtxId1]; MPoint p2 = points[vtxId2]; tri.v[0] = Corona::AnimatedPos(Corona::Pos(p0.x, p0.y, p0.z)); tri.v[1] = Corona::AnimatedPos(Corona::Pos(p1.x, p1.y, p1.z)); tri.v[2] = Corona::AnimatedPos(Corona::Pos(p2.x, p2.y, p2.z)); MVector n0 = normals[normalId0]; MVector n1 = normals[normalId1]; MVector n2 = normals[normalId2]; Corona::Dir dir0(n0.x, n0.y, n0.z); Corona::Dir dir1(n1.x, n1.y, n1.z); Corona::Dir dir2(n2.x, n2.y, n2.z); tri.n[0] = Corona::AnimatedDir(dir0); tri.n[1] = Corona::AnimatedDir(dir1); tri.n[2] = Corona::AnimatedDir(dir2); Corona::Pos uv0(uArray[uvId0],vArray[uvId0],0.0); Corona::Pos uv1(uArray[uvId1],vArray[uvId1],0.0); Corona::Pos uv2(uArray[uvId2],vArray[uvId2],0.0); Corona::StaticArray<Corona::Pos, 3> uvp; uvp[0] = uv0; uvp[1] = uv1; uvp[2] = uv2; tri.t.push(uvp); tri.materialId = 0; tri.displacement.min = displacementMin; tri.displacement.max = displacementMax; geom->addPrimitive(tri); }else{ Corona::TriangleData tri; tri.v = Corona::AnimatedPosI3(vtxId0, vtxId1, vtxId2); tri.n = Corona::AnimatedDirI3(normalId0, normalId1, normalId2); tri.t[0] = uvId0; tri.t[1] = uvId1; tri.t[2] = uvId2; tri.materialId = 0; geom->addPrimitive(tri); } } } }
void mesh::calculateTangents() { std::vector<float> tans(3*vertCount, 0); std::vector<float> bitans(3*vertCount, 0); tangents.resize(4 * vertCount); //calculate tentative tangents and bitangents for each triangle for (int i = 0; i < triCount; i++) { //find the vertices of the current triangle, and their UV coords int vi1 = triangles[3*i]; int vi2 = triangles[3*i + 1]; int vi3 = triangles[3*i + 2]; glm::vec3 vert0(vertices[3*vi1], vertices[3*vi1 + 1], vertices[3*vi1 + 2]); glm::vec3 vert1(vertices[3*vi2], vertices[3*vi2 + 1], vertices[3*vi2 + 2]); glm::vec3 vert2(vertices[3*vi3], vertices[3*vi3 + 1], vertices[3*vi3 + 2]); glm::vec2 uv0(texCoords[2*vi1], texCoords[2*vi1 + 1]); glm::vec2 uv1(texCoords[2*vi2], texCoords[2*vi2 + 1]); glm::vec2 uv2(texCoords[2*vi3], texCoords[2*vi3 + 1]); //differences in position and UV coords glm::vec3 dPos1 = vert1 - vert0; glm::vec3 dPos2 = vert2 - vert0; glm::vec2 dUV1 = uv1 - uv0; glm::vec2 dUV2 = uv2 - uv0; //calculate and store the tangent and bitangent float coeff = 1.0f / (dUV1.x * dUV2.y - dUV1.y * dUV2.x); glm::vec3 tan = dPos1 * dUV2.y - dPos2 * dUV1.y; glm::vec3 bitan = dPos2 * dUV1.x - dPos1 * dUV2.x; tan *= coeff; bitan *= coeff; tans[3*vi1] += tan.x; tans[3*vi1 + 1] += tan.y; tans[3*vi1 + 2] += tan.z; tans[3*vi2] += tan.x; tans[3*vi2 + 1] += tan.y; tans[3*vi2 + 2] += tan.z; tans[3*vi3] += tan.x; tans[3*vi3 + 1] += tan.y; tans[3*vi3 + 2] += tan.z; bitans[3*vi1] += bitan.x; bitans[3*vi1 + 1] += bitan.y; bitans[3*vi1 + 2] += bitan.z; bitans[3*vi2] += bitan.x; bitans[3*vi2 + 1] += bitan.y; bitans[3*vi2 + 2] += bitan.z; bitans[3*vi3] += bitan.x; bitans[3*vi3 + 1] += bitan.y; bitans[3*vi3 + 2] += bitan.z; } //find the final tangent (and bitangent) for each vertex for (int j = 0; j < vertCount; j++) { glm::vec3 normal (normals[3*j], normals[3*j + 1], normals[3*j + 2]); glm::vec3 tangent (tans[3*j], tans[3*j + 1], tans[3*j + 2]); glm::vec3 bitangent (bitans[3*j], bitans[3*j + 1], bitans[3*j + 2]); glm::normalize(tangent); glm::normalize(bitangent); //orthagonalize glm::vec3 tangent_orth(normal); tangent_orth *= glm::dot(normal, tangent); tangent_orth = tangent - tangent_orth; glm::normalize(tangent_orth); //compute handedness float handedness = 1.0f; glm::vec3 nCrossT = glm::cross(normal, tangent_orth); if(glm::dot(nCrossT, bitangent) > 0) { handedness = 1.0f; } else { handedness = -1.0f; } //store the orthagonalized tangent and handedness tangents[4*j] = tangent_orth.x; tangents[4*j + 1] = tangent_orth.y; tangents[4*j + 2] = tangent_orth.z; tangents[4*j + 3] = handedness; } }