Выдавливание нескольких полигонов с несколькими отверстиями и текстурирование комбинированной формы
Этот вопрос связан с этимвопрос,ответ показывает очень хороший способ выдавливания полигонов с отверстиями (см.отличный живой пример). Основное изучение ответа состояло в том, что пути в three.js (r58) не могут иметь более одной команды moveTo и должны находиться в начале пути, что означает, что путь должен быть нарушен с помощью moveTos, так что moveTo запускается всегда новый путь.
Выдавливание в three.js означает, что 2D-пути преобразуются в 3D-формы с использованием возможного скоса. Он подходит для выдавливания текстов для создания трехмерных букв и слов, но может также использоваться для выдавливания пользовательских путей.
Теперь возникает два вопроса:
как можно обрабатывать многоугольники, которые имеют многоугольники с отверстиями и многоугольники без дыр?как можно добавить текстуру к сгенерированной фигуре в целом?Я сделал пример этого как SVG вhttp://jsbin.com/oqomuj/1/edit:
Изображение создается по этому пути:
<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, чтобы ее можно было вытянуть, используя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):
И текстура применяется:
А поскольку сетка выдавливается, на приведенном выше рисунке также есть трехмерная толщина, но у вас есть идея текстурирования.
Я знаю, что y-координаты нужно перевернуть, но это тривиальная задача, а не вопрос моего вопроса, но если в Three.js есть готовая функция для отсечения y, это будет полезно.
Я потратил часы, чтобы изучить исходный код three.js, примеры идокументация, но поскольку наиболее часто встречающееся слово - «todo», оно не может сильно помочь. И я очень новичок в Three.js, я думаю, что это может быть тривиальной задачей для некоторых опытных пользователей Three.js.
ОБНОВЛЕНИЕ: И просто чтобы убедиться, что многоугольники отверстий всегда хорошо себя ведут, это означает, что многоугольники отверстий всегда полностью находятся внутри многоугольников материала, и нет повторяющихся вершин или самопересечений ни в многоугольниках материала, ни в многоугольниках отверстий, а во всех остальных. Материал-полигоны имеют порядок намотки CW и отверстия CCW.
ОБНОВЛЕНИЕ:, Объединение геометрий не было решением для текстурирования всего вытянутого многоугольника, заданного одной текстурой:http://jsfiddle.net/C5dga, Текстура повторяется для всех отдельных форм, поэтому объединение геометрий в этом случае не имеет никакого реального смысла. Возможно, можно найти решение по слиянию форм до их выдавливания, но пока не найдено решения для этого.