void CrossParam::ComputeTexCoordOnSurface2() { const boost::shared_ptr<MeshModel> p_mesh_1 = m_param_1.GetMeshModel(); const PolyIndexArray& face_index_array_1 = p_mesh_1->m_Kernel.GetFaceInfo().GetIndex(); const TexCoordArray& vtx_tex_coord_array_1 = p_mesh_1->m_Kernel.GetVertexInfo().GetTexCoord(); const boost::shared_ptr<MeshModel> p_mesh_2 = m_param_2.GetMeshModel(); int vert_num_2 = p_mesh_2->m_Kernel.GetModelInfo().GetVertexNum(); m_tex_coord_2.clear(); m_tex_coord_2.resize(vert_num_2); for(int vid=0; vid<vert_num_2; ++vid) { ParamCoord param_coord = m_param_2.GetParamCoord(vid); int cur_chart_id = m_param_2.GetVertexChartID(vid); int fid_in_mesh_1 = m_vtx_face_in_mesh_1[vid]; Coord barycentric = m_vtx_barycentric_in_mesh_1[vid]; const IndexArray& face_index = face_index_array_1[fid_in_mesh_1]; vector<TexCoord> tex_coord(3); for(size_t k=0; k<3; ++k) { int v = face_index[k]; tex_coord[k] = vtx_tex_coord_array_1[v]; } m_tex_coord_2[vid] = tex_coord[0]*barycentric[0] + tex_coord[1]*barycentric[1] + tex_coord[2]*barycentric[2]; } }
RenderablePlane::RenderablePlane(float length, float width, int length_segs, int width_segs, bool has_tex_coord, bool has_tangent) : RenderableHelper(L"RenderablePlane") { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleList); std::vector<int16_t> positions; for (int y = 0; y < width_segs + 1; ++ y) { for (int x = 0; x < length_segs + 1; ++ x) { float3 pos(static_cast<float>(x) / length_segs, 1 - (static_cast<float>(y) / width_segs), 0.5f); int16_t s_pos[4] = { static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.x() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.y() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.z() * 65535 - 32768), -32768, 32767)), 32767 }; positions.push_back(s_pos[0]); positions.push_back(s_pos[1]); positions.push_back(s_pos[2]); positions.push_back(s_pos[3]); } } ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(positions.size() * sizeof(positions[0])); init_data.slice_pitch = 0; init_data.data = &positions[0]; GraphicsBufferPtr pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(pos_vb, make_tuple(vertex_element(VEU_Position, 0, EF_SIGNED_ABGR16))); if (has_tex_coord) { std::vector<int16_t> tex_coords; for (int y = 0; y < width_segs + 1; ++ y) { for (int x = 0; x < length_segs + 1; ++ x) { float3 tex_coord(static_cast<float>(x) / length_segs * 0.5f + 0.5f, static_cast<float>(y) / width_segs * 0.5f + 0.5f, 0.5f); int16_t s_tc[2] = { static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.x() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.y() * 65535 - 32768), -32768, 32767)), }; tex_coords.push_back(s_tc[0]); tex_coords.push_back(s_tc[1]); } } init_data.row_pitch = static_cast<uint32_t>(tex_coords.size() * sizeof(tex_coords[0])); init_data.slice_pitch = 0; init_data.data = &tex_coords[0]; GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_TextureCoord, 0, EF_SIGNED_GR16))); } if (has_tangent) { std::vector<uint32_t> tangent(positions.size() / 4); ElementFormat fmt; if (rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ABGR8)) { fmt = EF_ABGR8; tangent.assign(tangent.size(), 0x807F7FFE); } else { BOOST_ASSERT(rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ARGB8)); fmt = EF_ARGB8; tangent.assign(tangent.size(), 0x80FE7F7F); } init_data.row_pitch = static_cast<uint32_t>(tangent.size() * sizeof(tangent[0])); init_data.slice_pitch = 0; init_data.data = &tangent[0]; GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_Tangent, 0, fmt))); } std::vector<uint16_t> index; for (int y = 0; y < width_segs; ++ y) { for (int x = 0; x < length_segs; ++ x) { index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0))); index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 0))); index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0))); } } init_data.row_pitch = static_cast<uint32_t>(index.size() * sizeof(index[0])); init_data.slice_pitch = 0; init_data.data = &index[0]; GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindIndexStream(ib, EF_R16UI); pos_aabb_ = AABBox(float3(-length / 2, -width / 2, 0), float3(+length / 2, +width / 2, 0)); tc_aabb_ = AABBox(float3(0, 0, 0), float3(1, 1, 0)); }
std::vector <osg::Vec2> LeafGrower::texture_coords_from_vertex(const std::vector <osg::Vec3>& all_v) { std::vector <osg::Vec2> ret; if(!is_loaded()) return ret; std::vector <osg::Vec3> ABEF(4, osg::Vec3(0, 0, 0));//planar leaves //for each vertex, find its texture coordinates for(unsigned int i=0; i<all_v.size(); i++) { osg::Vec3 v = all_v[i]; //find which quadrant does it lay osg::Vec3 normal = v - _cg; int region = which_quadrant(normal); //for rotation osg::Matrixf R; //front if(region == 0) R.makeIdentity(); //right, rotate to front by -120 if(region == 1) R.makeRotate(osg::Vec3(0, 1, 0), osg::Vec3(0.866025403, -0.5, 0)); //left, rotate to front by +120 if(region == 2) R.makeRotate(osg::Vec3(0, 1, 0), osg::Vec3(-0.866025403, -0.5, 0)); //top, rotate to front by -60 if(region == 3) //R.makeRotate(osg::Vec3(0, 0, 1), osg::Vec3(0, -1, 0)); R.makeRotate(osg::Vec3(0, 0, 1), osg::Vec3(0, -0.866025403, 0.5)); //bottom, rotate to front by +60 if(region == 4) //R.makeRotate(osg::Vec3(0, 0, -1), osg::Vec3(0, -1, 0)); R.makeRotate(osg::Vec3(0, 0, -1), osg::Vec3(0, -0.866025403, -0.5)); if(i%4 != 3) { ABEF[i%4] = v; continue; } else { ABEF[3] = v; //to prevent different corner points multiple to different rotations //so use the last R to apply to all for(int j=0; j<4; j++) { ABEF[j] = (ABEF[j]-_cg) * R + _cg; osg::Vec2 img_space = obj_to_img_space(ABEF[j]); //further transform it to real texture space by bound osg::Vec2 tex_space = img_space - _bound_bottomLeft;//for texture mapping, origin is at bottomLeft tex_space.y() *= -1.0f; //normalized it to within 0 <= x <= 1 osg::Vec2 tex_coord(tex_space.x()/float(_bound_width), tex_space.y()/float(_bound_height)); ret.push_back(tex_coord); } } } return ret; }