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

Tim*_*nen 4 svg textures polygon three.js

这个问题与这个问题有关.的回答显示出非常好的方式挤出有洞的多边形(见优秀的活生生的例子).答案的主要学习是,three.js(r58)中的路径不能有多个moveTo命令,它必须位于路径的开头,这意味着路径必须被moveTos打破,以便moveTo启动总是一条新路.

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

现在出现了两个问题:

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

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

在此输入图像描述

使用此路径生成图像:

<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):

在此输入图像描述

和纹理应用:

在此输入图像描述

而且由于网格是挤压的,上面还有3D厚度,但你有了纹理的想法.

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

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

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

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

Wes*_*ley 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 );
Run Code Online (Sandbox Code Playgroud)

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

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

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

var geometry1 = new THREE.ExtrudeGeometry( [ shape1, shape2 ], extrusionSettings );
Run Code Online (Sandbox Code Playgroud)

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