Wytłaczanie wielu wielokątów z wieloma otworami i teksturowanie połączonego kształtu
To pytanie jest z tym związanepytanie. Theodpowiedź pokazuje bardzo ładny sposób na wyciąganie wielokątów z otworami (patrzdoskonały przykład na żywo). Główną nauką odpowiedzi było to, że ścieżki w three.js (r58) nie mogą mieć więcej niż jednego polecenia moveTo i muszą znajdować się na początku ścieżki, co oznacza, że ścieżka musi zostać przerwana przez moveTos, aby ruch się zaczął zawsze nowa ścieżka.
Wyciąganie w three.js oznacza, że ścieżki 2D są konwertowane na kształty 3D przy użyciu możliwego ukosowania. Nadaje się do wytłaczania tekstów w celu tworzenia trójwymiarowych liter i słów, ale może być również wykorzystywany do wyciągania niestandardowych ścieżek.
Teraz pojawiają się dwa pytania:
jak można obsługiwać wielokąty, które mają wiele wielokątów otworu i wiele wielokątów bez otworów?jak można dodać teksturę do wygenerowanego kształtu jako całości?Zrobiłem przykład tego jako SVG whttp://jsbin.com/oqomuj/1/edit:
Obraz jest tworzony przy użyciu tej ścieżki:
<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>
i ta ścieżka została przekształcona w indywidualne tablice wierzchołków:
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}];
Pytanie brzmi, w jaki sposób ta podobna struktura może zostać przekonwertowana na obiekt 3D w three.js, aby można ją było wyciągnąć za pomocąTHREE.ExtrudeGeometry( shape, extrusionSettings )
a potem teksturowane jako całość?
Mogę zbadać dane ścieżki, aby wiedzieć, która dziura należy do tego wielokąta i obsłużyć wszystkie jako oddzielne kształty, ale ponieważ chcę użyćjeden obraz tekstury na wszystkich kształtach, Myślę, że preferowanym sposobem jest obsługa wszystkich materiałów-wielokątów jako jednego kształtu, a wielokątów otworów jako innego kształtu i użycie czegoś takiego:
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 );
Więc3d_geometry
powinien znajdować się na końcu jednej siatki, do której mogę dołączyć teksturę w ten sposób:
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 );
A jedną z tekstur może być coś takiego (256x256px):
I zastosowana tekstura:
A ponieważ siatka jest wytłaczana, na powyższym istnieje również grubość 3D, ale masz pomysł na teksturowanie.
Wiem, że współrzędne y muszą być odwrócone, ale jest to trywialne zadanie, a nie punkt mojego pytania, ale jeśli three.js ma gotową funkcję wycinania y, byłoby to pomocne.
Spędziłem wiele godzin na badaniu kodu źródłowego three.js, przykładów idokumentacja, ale ponieważ najczęstszym słowem jest „todo”, niewiele może pomóc. I jestem bardzo początkujący w three.js, pomyślałem, że może to być trywialne zadanie dla niektórych doświadczonych użytkowników three.js.
AKTUALIZACJA: I żeby mieć pewność, że wielokąty dziur są zawsze dobrze zachowane, co oznacza, że wieloboki dziur są zawsze w pełni wewnątrz materiału-wielokątów i nie ma duplikatów wierzchołków lub przecięć własnych w materialnych wielokątach lub wielokątach dziur i wszystkich materiał-wielokąty mają kolejność nawijania CW i otwory CCW.
UPDATE: Scalanie geometrii nie było rozwiązaniem do teksturowania całego wyciągniętego wielokąta ustawionego przez jedną teksturę:http://jsfiddle.net/C5dga. Tekstura jest powtarzana na wszystkich pojedynczych kształtach, więc scalanie geometrii w tym przypadku nie ma prawdziwego znaczenia. Rozwiązanie można znaleźć na łączeniu kształtów przed ich wytłoczeniem, ale jeszcze nie znaleziono rozwiązania.