挤出具有多个孔的多个多边形并对组合形状进行纹理化

时间:2013-04-20 20:10:57

标签: svg three.js textures polygon

此问题与此question有关。 answer显示了非常好的方法来挤出有孔的多边形(参见the excellent live example)。答案的主要学习是three.js(r58)中的路径不能有多个moveTo命令,它必须位于路径的开头,这意味着路径必须被moveTos打破,以便moveTo启动总是一条新路。

在three.js中挤出意味着使用可能的斜角将2D路径转换为3D形状。它适用于挤出文本以制作3D字母和单词,但也可用于拉伸自定义路径。

现在出现了两个问题:

  • 如何处理具有多个孔多边形和多个非孔多边形的多边形?
  • 如何将纹理添加到整个生成的形状中?

我在http://jsbin.com/oqomuj/1/edit中作为SVG做了一个例子:

enter image description here

使用以下路径生成图像:

<path d="
 M57.11,271.77 L57.11,218.33 L41.99,218.63 L105.49,165.77 L138.41,193.18 L138.41,172.2 L152.53,172.2 L152.53,204.93 L168.99,218.63 L153.21,218.63 L153.21,271.77Z
 M74.14,264.13 L105.49,264.13 L105.49,232.8 L74.14,232.8Z
 M115.35,250.7 L135.96,250.7 L135.96,232.61 L115.35,232.61Z
 M56.11,145.77 L56.11,92.33 L40.99,92.63 L104.49,39.77 L137.41,67.18 L137.41,46.2 L151.53,46.2 L151.53,78.93 L152.53,79.76 L155.55,77.23 L159.5,74.52 L168.65,69.81 L176.46,66.93 L188.04,64.16 L200.63,62.7 L213.65,62.7 L226.05,64.09 L234.83,66.06 L245.65,69.73 L252.87,73.27 L259.12,77.34 L262.63,80.33 L265.6,83.47 L268.01,86.76 L269.83,90.17 L271.08,93.68 L271.76,99.08 L271.04,104.64 L269.75,108.2 L267.87,111.63 L265.42,114.91 L262.44,118.01 L258.95,120.92 L255.02,123.63 L245.86,128.34 L238.06,131.22 L226.48,133.99 L213.88,135.44 L200.63,135.44 L188.04,133.99 L176.46,131.22 L168.65,128.34 L159.5,123.63 L155.55,120.92 L152.21,118.12 L152.21,145.77Z
 M73.14,138.13 L104.49,138.13 L104.49,106.8 L73.14,106.8Z
 M114.35,124.7 L134.96,124.7 L134.96,106.61 L114.35,106.61Z
 M207.26,117.33 L210.57,117.26 L216.87,116.53 L222.66,115.15 L227.8,113.18 L233.11,110 L236.34,106.99 L238.51,103.64 L239.42,100.48 L239.42,97.67 L238.51,94.51 L236.34,91.16 L233.11,88.15 L227.8,84.97 L222.66,83 L216.87,81.62 L210.57,80.89 L203.94,80.89 L197.65,81.62 L191.86,83 L186.71,84.97 L181.41,88.15 L178.18,91.16 L176.01,94.51 L175.1,97.67 L175.1,100.48 L176.01,103.64 L178.18,106.99 L181.41,110 L186.71,113.18 L191.86,115.15 L197.65,116.53 L203.94,117.26Z
"></path>

并将此路径转换为单个顶点数组:

var lower_house_material = [{x:57.11,y:271.77},{x:57.11,y:218.33},{x:41.99,y:218.63},{x:105.49,y:165.77},{x:138.42,y:193.18},{x:138.42,y:172.2},{x:152.53,y:172.2},{x:152.53,y:204.93},{x:168.99,y:218.63},{x:153.21,y:218.63},{x:153.21,y:271.77}];
var lower_house_hole_1 = [{x:74.14,y:264.13},{x:105.49,y:264.13},{x:105.49,y:232.8},{x:74.14,y:232.8}];
var lower_house_hole_2 = [{x:115.35,y:250.7},{x:135.96,y:250.7},{x:135.96,y:232.61},{x:115.35,y:232.61}];

var upper_house_material = [{x:56.11,y:145.77},{x:56.11,y:92.33},{x:40.99,y:92.63},{x:104.49,y:39.77},{x:137.42,y:67.18},{x:137.42,y:46.2},{x:151.53,y:46.2},{x:151.53,y:78.93},{x:152.53,y:79.76},{x:155.55,y:77.23},{x:159.5,y:74.52},{x:168.65,y:69.81},{x:176.46,y:66.93},{x:188.04,y:64.16},{x:200.63,y:62.7},{x:213.65,y:62.7},{x:226.05,y:64.1},{x:234.83,y:66.06},{x:245.65,y:69.73},{x:252.87,y:73.27},{x:259.12,y:77.35},{x:262.63,y:80.33},{x:265.6,y:83.47},{x:268.01,y:86.76},{x:269.84,y:90.17},{x:271.08,y:93.68},{x:271.76,y:99.08},{x:271.04,y:104.64},{x:269.75,y:108.2},{x:267.87,y:111.63},{x:265.42,y:114.91},{x:262.44,y:118.01},{x:258.96,y:120.92},{x:255.02,y:123.63},{x:245.86,y:128.34},{x:238.06,y:131.22},{x:226.48,y:133.99},{x:213.88,y:135.45},{x:200.63,y:135.45},{x:188.04,y:133.99},{x:176.46,y:131.22},{x:168.65,y:128.34},{x:159.5,y:123.63},{x:155.55,y:120.92},{x:152.21,y:118.12},{x:152.21,y:145.77}];
var upper_house_hole_1 = [{x:73.14,y:138.13},{x:104.49,y:138.13},{x:104.49,y:106.8},{x:73.14,y:106.8}];
var upper_house_hole_2 = [{x:114.35,y:124.7},{x:134.96,y:124.7},{x:134.96,y:106.61},{x:114.35,y:106.61}];
var upper_house_hole_3 = [{x:207.26,y:117.33},{x:210.57,y:117.26},{x:216.87,y:116.53},{x:222.66,y:115.15},{x:227.8,y:113.18},{x:233.11,y:110},{x:236.34,y:106.99},{x:238.51,y:103.64},{x:239.42,y:100.48},{x:239.42,y:97.67},{x:238.51,y:94.51},{x:236.34,y:91.16},{x:233.11,y:88.15},{x:227.8,y:84.97},{x:222.66,y:83},{x:216.87,y:81.62},{x:210.57,y:80.89},{x:203.94,y:80.89},{x:197.65,y:81.62},{x:191.86,y:83},{x:186.71,y:84.97},{x:181.41,y:88.15},{x:178.18,y:91.16},{x:176.01,y:94.51},{x:175.1,y:97.67},{x:175.1,y:100.48},{x:176.01,y:103.64},{x:178.18,y:106.99},{x:181.41,y:110},{x:186.71,y:113.18},{x:191.86,y:115.15},{x:197.65,y:116.53},{x:203.94,y:117.26}];

问题是,这个类似的结构如何在three.js中转换为3D对象,以便可以使用THREE.ExtrudeGeometry( shape, extrusionSettings )进行挤压,然后将其作为一个整体进行纹理化?

我可以检查路径数据以了解哪个孔属于哪个多边形并将所有孔作为单独的形状处理,但因为我想在所有形状中使用一个纹理图像,我认为首选方式是将所有材质多边形作为一个形状处理,将孔多边形作为其他形状处理,并使用如下内容:

var shape = [lower_house_material, upper_house_material];
shape.holes = [lower_house_hole_1, lower_house_hole_2, upper_house_hole_1, upper_house_hole_2, upper_house_hole_3];
var 3d_geometry = THREE.ExtrudeGeometry( shape, extrusionSettings );

所以3d_geometry应该在一个网格的末尾,我可以用这样的方式添加纹理:

var textureFront = new THREE.ImageUtils.loadTexture( 'textureFront.png');
var textureSide = new THREE.ImageUtils.loadTexture( 'textureSide.png');
var materialFront = new THREE.MeshBasicMaterial( { map: textureFront } );
var materialSide = new THREE.MeshBasicMaterial( { map: textureSide } );
var materialArray = [ materialFront, materialSide ];
var faceMaterial = new THREE.MeshFaceMaterial(materialArray);
var final_mesh = new THREE.Mesh(3d_geometry, faceMaterial );

其中一个纹理可能是这样的(256x256px):

enter image description here

纹理应用:

enter image description here

由于网格被拉伸,上面还有3D厚度,但你有了纹理的想法。

我知道必须翻转y坐标,但这是一项微不足道的任务而不是我的问题,但如果three.js有现成的剪辑功能,那将会有所帮助。

我花了几个小时来检查three.js源代码,例子和documentation,但是因为最常见的词是“todo”,所以它无济于事。而且我对three.js很新手,我认为对于一些经验丰富的three.js用户来说这可能是一项微不足道的任务。

更新:并且为了确保,孔多边形总是表现良好,这意味着孔多边形总是完全在材料多边形内部,并且在材料多边形或孔中没有重复的顶点或自交叉 - 多边形和所有材料多边形都有CW绕组顺序和孔CCW。

更新:合并几何图形不是通过一个纹理对整个拉伸多边形集进行纹理化的解决方案:http://jsfiddle.net/C5dga。纹理在所有单独的形状上重复,因此在这种情况下合并几何形状没有实际意义。解决方案可能在挤出之前合并形状时找到,但尚未找到解决方案。

1 个答案:

答案 0 :(得分:5)

您可以像下面的代码段一样合并几何图形,从而只生成一个网格。根据您之前的问题,您已经知道如何纹理单个几何体。

var geometry1 = new THREE.ExtrudeGeometry( shape1, extrusionSettings );
var geometry2 = new THREE.ExtrudeGeometry( shape2, extrusionSettings );

geometry1.merge( geometry2 );

. . .

var mesh = new THREE.Mesh( geometry1, material );

scene.add( mesh );

小提琴:http://jsfiddle.net/pHn2B/88/

小提琴:http://jsfiddle.net/C5dga/13/(带纹理)

编辑:作为创建单独几何图形和使用merge实用程序的替代方法,您可以使用以下模式创建单个几何图形,而不是:

var geometry1 = new THREE.ExtrudeGeometry( [ shape1, shape2 ], extrusionSettings );

编辑:更新为three.js r.70