Преобразование путей SVG с отверстиями в вытянутые фигуры в three.js

У меня есть форма, которая состоит из 4 многоугольников: 2 без отверстия и 2 отверстия. Это только пример. В действительности может существовать форма, состоящая из 50 многоугольников, из которых 20 - это не дырки, а 30 - дырки. В пути SVG этот многоугольник можно легко представить, комбинируя moveto:s и lineto:s. Каждый подполигон (отверстие или не отверстие) в строке пути начинается с команды moveto и заканчивается командой z (end), а для не отверстий порядок намотки CW и отверстия CCW. Очень просто и интуитивно понятно.

Форма в SVG представляется следующим образом ( http://jsbin.com/osoxev/1/edit):

<путь d = "M305,08,241,97 L306,251,51 L308,18,256,39 L311,72,259,09 L317,31,260,01 L324,71,259,01 L332,45,255,86 L335,57,257,53 L337,6260,44 L336,94,262,33 L328,27,268,267 286,267,272,267,272,267,216,216,216,216,216,216,216,217,216,217,216,216,219,216,216,216,216,217,36,217,216 можно было вы отвечаете за L.28,227,926,267,267,267,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,217,21,216,216,216,61,316,41,216,216,31,216,216,61 можно было выявлять L279.78,269.31 L274.14,263.55 L271.65,260.21 L269.2,261.06 L254.83,268.51 L242.11,272.97 L227.59,275.23 L209.91,275.48 L197.47,273.63 L187.91,270.13 L180.48,265.09 L175.32,258.88 L172.2,251.44 L171.1,242.23 L172.24,233.63 L175.49,226.24 L181, 219,54 L189,42,213,3 L201,36,207,73 L217,203,125 L238,28,200,1 L265,24,198,78 L269,37,198,47 L269,98 182,93 L268,74 171,32 L266,05 163,7 L261,58,157,72 L255,224,115,215,115,215,215,215,215,215,215,215.64,160.85 L207.19,165.28 L209.34,169.86 L212.01,174.15 L212.14,177.99 L209.8,181.78 L204.22,185.79 L197.62,187.68 L188.65,187.43 L182.41,185.39 L178.45,181.77 L176.2,176.9 L176.03,170.64 L178.2,164.13 L183.09,157.69 L191.04,151.36 L202.01,145.82 L216,09,141,57 L232,08,139,24 L250,0 7 139,18 L266,1341,23 L279,05 145,06 L289,15,30,3 L295,91,156,19 L300,7363,41 L303,85 172,47 L305,07 183,78 L305,07 241,97 L305,08 241,97Z 

M243,99,64,95 L255,92,66,06 L266,21,99,28 L274,98,74,44 L280,64,80,19 L284,02,86,85 L285,26,94,52 L284,27,102,84 L281,24,109,66 L276,03,115,43 L267,89,120,46 L257,68 L245,79,125,33 L232,93,124,53 L222,21,11,74 L213,14,117,11 L207,36,111,92 L203,7,105,75 L201,94,98,18 L202,34,90,12 L204,86,83,4 L210,01,76,81 L217,49,71,33 L227,17. 35,65,2 L243,75,64,95 L243,99,64,95Z

M269,99,212,88 L269,48,208,76 L266,59,208,36 L245,76,210,86 L230,95,214,67 L220,9,219,34 L213,82,224,85 L209,69,230,71 L207,92,237,03 L208,4,244,259,2252,252 L2,225 L2,22,225 07 250,04 L269,34 247,02 L269,9944,81 L269,99122,88 L269,99,212,88Z

M243,63,73,34 L235,93,74,4 L230,07,77,36 L225,65,82,21 L223,05,88,57 L222,41,96,92 L223,94,104,53 L227,23,110,22 L231,99,114,29 L238,44,116,65 L246,81,116,94 L253,73,115,1 87 111,5 L262,63,106,12 L264,64,98,93 L264,59,90,25 L262,47,83,41 L258,65,78,43 L253,37,75,08 L246,08,73,43 L243,68,73,34 L243,63,73,34Z "/>

Когда я пытаюсь следовать той же логике в three.js, я сталкиваюсь с проблемами. Ниже изображение этого:

введите описание изображения здесь

Three.js, похоже, не понимает, что означает moveto. Он должен сделать "перо вверх" и ничего не рисовать между предыдущей точкой и точкой команды moveto. Но "ручка не поднимается" и форма ломается.

Вот часть кода (не путайте имена переменных, они из другого примера):

// Создать форму глифа (извините за запутанное имя):
var starPoints2 = new THREE.Shape();

// Добавить первый полигон starPoints2.moveTo(307.94,275.49);
starPoints2.lineTo(296.26,275.23);
// .....
starPoints2.lineTo(286.64,272.99);
starPoints2.lineTo(307.94,275.49);

// Добавить второй полигон starPoints2.moveTo(245.79,125.33);
starPoints2.lineTo(232.93,124.53);
// .....
starPoints2.lineTo(257.68,123.93);
starPoints2.lineTo(245.79,125.33);

// Создать путь для отверстий var smileyEye1Path = new THREE.Path();

// Первое отверстие smileyEye1Path.moveTo(221.69,258.13);
smileyEye1Path.lineTo(215.2,255.08);
// .....
smileyEye1Path.lineTo(230.57,259.43);
smileyEye1Path.lineTo(221.69,258.13);

// Второе отверстие smileyEye1Path.moveTo(238.44,116.65);
smileyEye1Path.lineTo(231.99,114.29);
// .....
smileyEye1Path.lineTo(246.81,116.94);
smileyEye1Path.lineTo(238.44,116.65);

// Добавить отверстия в форму var starShape = starPoints2;
starShape.holes.push( smileyEye1Path);

// Выдавливаем после этого. Смотрите полный код здесь: // http://jsfiddle.net/pHn2B/33/

function(){} http://jsfiddle.net/pHn2B/33/

Что я делаю не так в моем коде или есть ошибка в three.js?

1 ответ

Решение

Вы не можете иметь moveTo в середине определения формы. Вы должны иметь две отдельные фигуры. Вы можете сделать что-то вроде этого:

var object = new THREE.Object3D();

var shape1 = new THREE.Shape();
var shape2 = new THREE.Shape();

var hole1 = new THREE.Path();
var hole2 = new THREE.Path();

shape1.holes.push( hole1 );
shape2.holes.push( hole2 );

. . .

object.add( mesh1 );
object.add( mesh2 );

scene.add( object );

Скрипка: http://jsfiddle.net/pHn2B/34/

three.js r.58

PS Дружественный совет: в будущем было бы неплохо упростить людям помощь - отредактируйте имена переменных и удалите несвязанный код из вашего примера.

Другие вопросы по тегам