Этот вопрос связан с этим вопросом . ответ показывает очень хороший способ выдавливания многоугольников с отверстиями (см. отличный живой пример ). Основное изучение ответа заключалось в том, что пути в three.js (r58) не могут иметь более одной команды moveTo и должны находиться в начале пути, что означает, что путь должен быть прерван с помощью moveTos, так что moveTo start всегда новый путь.
Экструзия в 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}];
Вопрос в том, как эту подобную структуру можно преобразовать в 3D-объект в 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):
И текстура применена:
И поскольку сетка выдавлена, на приведенном выше изображении также присутствует 3D-толщина, но у вас есть идея текстурирования.
Я знаю, что y-координаты нужно перевернуть, но это тривиальная задача, и это не мой вопрос, но если у three.js есть готовая функция для обрезки y, это было бы полезно.
Я потратил часы на изучение исходного кода three.js, примеров и документации , но из-за того, что чаще всего встречается слово «todo», это не может сильно помочь. И я новичок в three.js, думаю, это может быть тривиальная задача для опытного пользователя three.js.
ОБНОВЛЕНИЕ: И чтобы убедиться, что полигоны отверстий всегда хорошо себя ведут, это означает, что полигоны отверстий всегда полностью внутри полигонов материала, и нет повторяющихся вершин или самопересечений ни в полигонах материалов, ни в полигонах дырок, и все такое. материалы-полигоны имеют порядок намотки по часовой стрелке, а отверстия - против часовой.
ОБНОВЛЕНИЕ: слияние геометрий не было решением для текстурирования всего выдавленного многоугольника, заданного одной текстурой: http://jsfiddle.net/C5dga. Текстура повторяется на всех отдельных формах, поэтому слияние геометрий в этом случае не имеет реального значения. Решение, возможно, можно найти при объединении форм до того, как они будут выдавлены, но решения для этого еще не найдено.
1 ответ
Вы можете объединить геометрии, как в следующем фрагменте, в результате чего получится только одна сетка. Судя по предыдущим вопросам, вы уже знаете, как текстурировать отдельную геометрию.
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 );
Fiddle: http://jsfiddle.net/pHn2B/88/
Fiddle: http://jsfiddle.net/C5dga/13/ (с текстурой)
РЕДАКТИРОВАТЬ: В качестве альтернативы созданию отдельных геометрий и использованию утилиты merge
вы можете вместо этого создать единую геометрию, используя следующий шаблон:
var geometry1 = new THREE.ExtrudeGeometry( [ shape1, shape2 ], extrusionSettings );
РЕДАКТИРОВАТЬ: обновлено до three.js r.70
Похожие вопросы
Связанные вопросы
Новые вопросы
svg
Масштабируемая векторная графика (SVG) — это основанный на XML формат двумерной векторной графики, который также можно использовать в HTML. Не добавляйте этот тег только потому, что ваш проект использует SVG. Вместо этого добавьте тег, если ваш вопрос касается SVG или тесно связан с ним, например, как добиться чего-либо с помощью SVG.