2011-11-30 13 views

Odpowiedz

40

Niby tak, istnieje wiele możliwości:

  1. poprzez hierarchię można po prostu dodać jedno oczko do drugiego za pomocą add() funkcję
  2. poprzez merge() funkcji GeometryUtil do scalania wierzchołki i oczka dwóch obiektów Geometry w jednym z podstawowych edytorów 3D obsługujących operacje Boole'a między siatkami i eksportowaniem.

Metoda 1 jest całkiem prosta:

var sphere = new THREE.Mesh(new THREE.SphereGeometry(100,16,12),new THREE.MeshLambertMaterial({ color: 0x2D303D, wireframe: true, shading: THREE.FlatShading })); 
       var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false),new THREE.MeshLambertMaterial({ color: 0x2D303D, wireframe: true, shading: THREE.FlatShading })); 
       cylinder.position.y = -100; 
       scene.add(sphere); 
       scene.add(cylinder); 

Zauważ, że 16 powtarza się, więc podziały poziomie w jednym z siatki odpowiada drugi (za przyzwoity wygląd)

Metoda 2.1 - poprzez GeometryUtils

//make a sphere 
       var sg = new THREE.SphereGeometry(100,16,12); 
       //make cylinder - ideally the segmentation would be similar to predictable results 
       var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false); 
       //move vertices down for cylinder, so it maches half the sphere - offset pivot 
       for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100; 
       //merge meshes 
       THREE.GeometryUtils.merge(sg,cg); 
       var mesh = new THREE.Mesh(sg,new THREE.MeshLambertMaterial({ color: 0x2D303D, wireframe: true, shading: THREE.FlatShading })); 
       scene.add(mesh); 

Sposób 2,2 scalanie Lathe half-sphere i cylinder:

var pts = [];//points array 
       var detail = .1;//half-circle detail - how many angle increments will be used to generate points 
       var radius = 100;//radius for half_sphere 
       var total = Math.PI * .51; 
       for(var angle = 0.0; angle < total ; angle+= detail)//loop from 0.0 radians to PI (0 - 180 degrees) 
        pts.push(new THREE.Vector3(0,Math.cos(angle) * radius,Math.sin(angle) * radius));//angle/radius to x,z 
       var lathe = new THREE.LatheGeometry(pts, 16);//create the lathe with 12 radial repetitions of the profile 
       //rotate vertices in lathe geometry by 90 degrees 
       var rx90 = new THREE.Matrix4(); 
       rx90.setRotationFromEuler(new THREE.Vector3(-Math.PI * .5,0,0)); 
       lathe.applyMatrix(rx90); 
       //make cylinder - ideally the segmentation would be similar for predictable results 
       var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false); 
       //move vertices down for cylinder, so it maches half the sphere 
       for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100; 
       //merge meshes 
       THREE.GeometryUtils.merge(lathe,cg); 
       var mesh = new THREE.Mesh(lathe, new THREE.MeshLambertMaterial({ color: 0x2D303D, wireframe: true, shading: THREE.FlatShading })); 
       mesh.position.y = 150; 
       scene.add(mesh); 

Jedyny problem, na który nie mogę odpowiedzieć w tej chwili, pochodzi z twarzy znajdujących się wewnątrz siatki. Najlepiej byłoby, gdyby normalne były odwrócone, aby nie były renderowane, ale nie znalazły na to szybkiego rozwiązania.

Trzeci jest dość prosty. Większość pakietów 3D zezwala na operację Boolean na siatkach (np. Łączenie dwóch siatek razem z operacją ADD (meshA + meshB)). Spróbuj utworzyć cylinder i kulę w Blender (darmowy, otwarty), który ma już eksporter three.js. Alternatywnie możesz wyeksportować plik .obj połączonych siatek z edytora lub edytora 3d i użyć skryptu convert_obj_three.

Aktualizacja

Znalazłem jeszcze inny sposób, który może być łatwiejsze/bardziej intuicyjne. Pamiętasz operacje boolowskie, o których wspomniałem powyżej?

Okazuje się, że jest to niesamowite js biblioteki tylko, że: Constructive Solid Geometry:

CSG library preview from owner's github page

Chandler Prall napisał kilka przydatnych funkcji, aby połączyć CSG with three.js. Więc z biblioteki CSG i three.js wrapper for it, można po prostu to zrobić:

var cylinder = THREE.CSG.toCSG(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false),new THREE.Vector3(0,-100,0)); 
var sphere = THREE.CSG.toCSG(new THREE.SphereGeometry(100,16,12)); 
var geometry = cylinder.union(sphere); 
var mesh  = new THREE.Mesh(THREE.CSG.fromCSG(geometry),new THREE.MeshNormalMaterial()); 

co daje piękny efekt (żadnych problemów z dodatkowych twarzy/obracanie normalnych/etc.):

cylinder-sphere union with CSG and three.js

+0

Próbuję tych wszystkich rzeczy, dziękuję za odpowiedzi! Zadałem to pytanie, ponieważ próbuję stworzyć kwiat 3D z wieloma kształtami i teksturami. Mój cel wiązania kształtów, więc mogę obracać i przeciągać całe kształty kwiatów, a nie każdy kształt razem jako jeden kształt. – BorisD

+0

Brzmi trochę jak [aplikacja HelloFit HelloFlower] (http://helloenjoy.com/helloflower/). W tym przypadku powiedziałbym, że mam pusty "obiekt" Object3D u góry, a następnie 'dodaj()' płatki, słupek, itp. Do tego, aby można było manipulować grupą razem. Coś jak pierwsza sugestia, ale zamiast dodawać prosto do sceny, dodawanie do kontenera ('scene.add (kontener), container.add (flowerPartA), container.add (flowerPartB), // itd.) –

+0

Wow ! to świetny przykład człowieka ... nie dokładnie tego, co próbuję zbudować, ale są pewne podobne rzeczy. Przez ostatnie kilka dni miałem dobry postęp. Mam nadzieję, że mój ostatni przykład, który opublikuję, pomoże początkującemu w Three.js rozwiązać niektóre małe i większe problemy. Ale wciąż jest kilka drobnych rzeczy, których jeszcze nie znam ... Jak mogę stworzyć coś w rodzaju cylindrycznego kształtu, który zaczyna się w punkcie X i kończy w punkcie Y ... na razie jedyną rzeczą, którą mogę wymyślić jest właśnie zrobienie cylinder i obrócić go? – BorisD