geometry.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package collada
  5. import (
  6. "fmt"
  7. "reflect"
  8. "strings"
  9. "github.com/g3n/engine/geometry"
  10. "github.com/g3n/engine/gls"
  11. "github.com/g3n/engine/math32"
  12. )
  13. // GetGeometry returns a pointer to an instance of the geometry
  14. // with the specified id in the Collada document, its primitive type
  15. // and an error. If no previous instance of the geometry was found
  16. // the geometry is created
  17. func (d *Decoder) GetGeometry(id string) (geometry.IGeometry, uint32, error) {
  18. // If geometry already created, returns it
  19. ginst, ok := d.geometries[id]
  20. if ok {
  21. return ginst.geom, ginst.ptype, nil
  22. }
  23. // Creates geometry and saves it associated with its id
  24. geom, ptype, err := d.NewGeometry(id)
  25. if err != nil {
  26. return nil, 0, err
  27. }
  28. d.geometries[id] = geomInstance{geom, ptype}
  29. return geom, ptype, nil
  30. }
  31. // NewGeometry creates and returns a pointer to a new instance of the geometry
  32. // with the specified id in the Collada document, its primitive type and and error.
  33. func (d *Decoder) NewGeometry(id string) (geometry.IGeometry, uint32, error) {
  34. id = strings.TrimPrefix(id, "#")
  35. // Look for geometry with specified id in the dom
  36. var geo *Geometry
  37. for _, g := range d.dom.LibraryGeometries.Geometry {
  38. if g.Id == id {
  39. geo = g
  40. break
  41. }
  42. }
  43. if geo == nil {
  44. return nil, 0, fmt.Errorf("Geometry:%s not found", id)
  45. }
  46. // Geometry type
  47. switch gt := geo.GeometricElement.(type) {
  48. // Collada mesh category includes points, lines, linestrips, triangles,
  49. // triangle fans, triangle strips and polygons.
  50. case *Mesh:
  51. return newMesh(gt)
  52. // B-Spline
  53. // Bezier
  54. // NURBS
  55. // Patch
  56. default:
  57. return nil, 0, fmt.Errorf("GeometryElement:%T not supported", gt)
  58. }
  59. }
  60. func newMesh(m *Mesh) (*geometry.Geometry, uint32, error) {
  61. // If no primitive elements present, it is a mesh of points
  62. if len(m.PrimitiveElements) == 0 {
  63. return newMeshPoints(m)
  64. }
  65. // All the primitive elements must be of the same type
  66. var etype reflect.Type
  67. for i := 0; i < len(m.PrimitiveElements); i++ {
  68. el := m.PrimitiveElements[i]
  69. if i == 0 {
  70. etype = reflect.TypeOf(el)
  71. } else {
  72. if reflect.TypeOf(el) != etype {
  73. return nil, 0, fmt.Errorf("primitive elements of different types")
  74. }
  75. }
  76. }
  77. pei := m.PrimitiveElements[0]
  78. switch pet := pei.(type) {
  79. case *Polylist:
  80. return newMeshPolylist(m, m.PrimitiveElements)
  81. case *Triangles:
  82. return newMeshTriangles(m, pet)
  83. case *Lines:
  84. return newMeshLines(m, pet)
  85. case *LineStrips:
  86. return newMeshLineStrips(m, pet)
  87. case *Trifans:
  88. return newMeshTrifans(m, pet)
  89. case *Tristrips:
  90. return newMeshTristrips(m, pet)
  91. default:
  92. return nil, 0, fmt.Errorf("PrimitiveElement:%T not supported", pet)
  93. }
  94. }
  95. // Creates a geometry from a polylist
  96. // Only triangles are supported
  97. func newMeshPolylist(m *Mesh, pels []interface{}) (*geometry.Geometry, uint32, error) {
  98. // Get vertices positions
  99. if len(m.Vertices.Input) != 1 {
  100. return nil, 0, fmt.Errorf("Mesh.Vertices.Input length not supported")
  101. }
  102. vinp := m.Vertices.Input[0]
  103. if vinp.Semantic != "POSITION" {
  104. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Semantic:%s not supported", vinp.Semantic)
  105. }
  106. // Get vertices input source
  107. inps := getMeshSource(m, vinp.Source)
  108. if inps == nil {
  109. return nil, 0, fmt.Errorf("Source:%s not found", vinp.Source)
  110. }
  111. // Get vertices input float array
  112. // Ignore Accessor (??)
  113. posArray, ok := inps.ArrayElement.(*FloatArray)
  114. if !ok {
  115. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Source not FloatArray")
  116. }
  117. // Creates buffers
  118. positions := math32.NewArrayF32(0, 0)
  119. normals := math32.NewArrayF32(0, 0)
  120. uvs := math32.NewArrayF32(0, 0)
  121. indices := math32.NewArrayU32(0, 0)
  122. // Creates vertices attributes map for reusing indices
  123. mVindex := make(map[[8]float32]uint32)
  124. var index uint32
  125. geomGroups := make([]geometry.Group, 0)
  126. groupMatindex := 0
  127. // For each Polylist
  128. for _, pel := range pels {
  129. // Checks if element is Polylist
  130. pl, ok := pel.(*Polylist)
  131. if !ok {
  132. return nil, 0, fmt.Errorf("Element is not a Polylist")
  133. }
  134. // If Polylist has not inputs, ignore
  135. if pl.Input == nil || len(pl.Input) == 0 {
  136. continue
  137. }
  138. // Checks if all Vcount elements are triangles
  139. for _, v := range pl.Vcount {
  140. if v != 3 {
  141. return nil, 0, fmt.Errorf("Only triangles are supported in Polylist")
  142. }
  143. }
  144. // Get VERTEX input
  145. inpVertex := getInputSemantic(pl.Input, "VERTEX")
  146. if inpVertex == nil {
  147. return nil, 0, fmt.Errorf("VERTEX input not found")
  148. }
  149. // Get optional NORMAL input
  150. inpNormal := getInputSemantic(pl.Input, "NORMAL")
  151. var normArray *FloatArray
  152. if inpNormal != nil {
  153. // Get normals source
  154. source := getMeshSource(m, inpNormal.Source)
  155. if source == nil {
  156. return nil, 0, fmt.Errorf("NORMAL source:%s not found", inpNormal.Source)
  157. }
  158. // Get normals source float array
  159. normArray, ok = source.ArrayElement.(*FloatArray)
  160. if !ok {
  161. return nil, 0, fmt.Errorf("NORMAL source:%s not float array", inpNormal.Source)
  162. }
  163. }
  164. // Get optional TEXCOORD input
  165. inpTexcoord := getInputSemantic(pl.Input, "TEXCOORD")
  166. var texArray *FloatArray
  167. if inpTexcoord != nil {
  168. // Get texture coordinates source
  169. source := getMeshSource(m, inpTexcoord.Source)
  170. if source == nil {
  171. return nil, 0, fmt.Errorf("TEXCOORD source:%s not found", inpTexcoord.Source)
  172. }
  173. // Get texture coordinates source float array
  174. texArray, ok = source.ArrayElement.(*FloatArray)
  175. if !ok {
  176. return nil, 0, fmt.Errorf("TEXCOORD source:%s not float array", inpTexcoord.Source)
  177. }
  178. }
  179. // Initialize geometry group
  180. groupStart := indices.Size()
  181. // For each primitive index
  182. inputCount := len(pl.Input)
  183. for i := 0; i < len(pl.P); i += inputCount {
  184. // Vertex attributes: position(3) + normal(3) + uv(2)
  185. var vx [8]float32
  186. // Vertex position
  187. posIndex := pl.P[i+inpVertex.Offset] * 3
  188. // Get position vector and appends to its buffer
  189. vx[0] = posArray.Data[posIndex]
  190. vx[1] = posArray.Data[posIndex+1]
  191. vx[2] = posArray.Data[posIndex+2]
  192. // Optional vertex normal
  193. if inpNormal != nil {
  194. // Get normal index from P
  195. normIndex := pl.P[i+inpNormal.Offset] * 3
  196. // Get normal vector and appends to its buffer
  197. vx[3] = normArray.Data[normIndex]
  198. vx[4] = normArray.Data[normIndex+1]
  199. vx[5] = normArray.Data[normIndex+2]
  200. }
  201. // Optional vertex texture coordinate
  202. if inpTexcoord != nil {
  203. // Get normal index from P
  204. texIndex := pl.P[i+inpTexcoord.Offset] * 2
  205. // Get normal vector and appends to its buffer
  206. vx[6] = texArray.Data[texIndex]
  207. vx[7] = texArray.Data[texIndex+1]
  208. }
  209. // If this vertex and its attributes has already been appended,
  210. // reuse it, adding its index to the index buffer
  211. // to reuse its index
  212. idx, ok := mVindex[vx]
  213. if ok {
  214. indices.Append(idx)
  215. continue
  216. }
  217. // Appends new vertex position and attributes to its buffers
  218. positions.Append(vx[0], vx[1], vx[2])
  219. if inpNormal != nil {
  220. normals.Append(vx[3], vx[4], vx[5])
  221. }
  222. if inpTexcoord != nil {
  223. uvs.Append(vx[6], vx[7])
  224. }
  225. indices.Append(index)
  226. // Save the index to this vertex position and attributes for
  227. // future reuse
  228. mVindex[vx] = index
  229. index++
  230. }
  231. // Adds this geometry group to the list
  232. geomGroups = append(geomGroups, geometry.Group{
  233. Start: groupStart,
  234. Count: indices.Size() - groupStart,
  235. Matindex: groupMatindex,
  236. Matid: pl.Material,
  237. })
  238. groupMatindex++
  239. }
  240. // Debug dump
  241. //for i := 0; i < positions.Size()/3; i++ {
  242. // vidx := i*3
  243. // msg := fmt.Sprintf("i:%2d position:%v %v %v",
  244. // i, positions.Get(vidx), positions.Get(vidx+1), positions.Get(vidx+2))
  245. // if normals.Size() > 0 {
  246. // msg += fmt.Sprintf("\tnormal:%v %v %v",
  247. // normals.Get(vidx), normals.Get(vidx+1), normals.Get(vidx+2))
  248. // }
  249. // if uvs.Size() > 0 {
  250. // msg += fmt.Sprintf("\tuv:%v %v", uvs.Get(i*2), uvs.Get(i*2+1))
  251. // }
  252. // log.Debug("%s", msg)
  253. //}
  254. //log.Debug("indices(%d):%v", indices.Size(), indices)
  255. //log.Debug("groups:%v", geomGroups)
  256. // Creates geometry
  257. geom := geometry.NewGeometry()
  258. // Creates VBO with vertex positions
  259. geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  260. // Creates VBO with vertex normals
  261. if normals.Size() > 0 {
  262. geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
  263. }
  264. // Creates VBO with uv coordinates
  265. if uvs.Size() > 0 {
  266. geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
  267. }
  268. // Sets the geometry indices buffer
  269. geom.SetIndices(indices)
  270. // Add material groups to the geometry
  271. geom.AddGroupList(geomGroups)
  272. return geom, gls.TRIANGLES, nil
  273. }
  274. func newMeshTriangles(m *Mesh, tr *Triangles) (*geometry.Geometry, uint32, error) {
  275. // Get vertices positions
  276. if len(m.Vertices.Input) != 1 {
  277. return nil, 0, fmt.Errorf("Mesh.Vertices.Input length not supported")
  278. }
  279. vinp := m.Vertices.Input[0]
  280. if vinp.Semantic != "POSITION" {
  281. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Semantic:%s not supported", vinp.Semantic)
  282. }
  283. // Get vertices input source
  284. inps := getMeshSource(m, vinp.Source)
  285. if inps == nil {
  286. return nil, 0, fmt.Errorf("Source:%s not found", vinp.Source)
  287. }
  288. // Get vertices input float array
  289. // Ignore Accessor (??)
  290. posArray, ok := inps.ArrayElement.(*FloatArray)
  291. if !ok {
  292. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Source not FloatArray")
  293. }
  294. // Creates buffers
  295. positions := math32.NewArrayF32(0, 0)
  296. normals := math32.NewArrayF32(0, 0)
  297. uvs := math32.NewArrayF32(0, 0)
  298. indices := math32.NewArrayU32(0, 0)
  299. // Creates vertices attributes map for reusing indices
  300. mVindex := make(map[[8]float32]uint32)
  301. var index uint32
  302. geomGroups := make([]geometry.Group, 0)
  303. groupMatindex := 0
  304. // Get VERTEX input
  305. inpVertex := getInputSemantic(tr.Input, "VERTEX")
  306. if inpVertex == nil {
  307. return nil, 0, fmt.Errorf("VERTEX input not found")
  308. }
  309. // Get optional NORMAL input
  310. inpNormal := getInputSemantic(tr.Input, "NORMAL")
  311. var normArray *FloatArray
  312. if inpNormal != nil {
  313. // Get normals source
  314. source := getMeshSource(m, inpNormal.Source)
  315. if source == nil {
  316. return nil, 0, fmt.Errorf("NORMAL source:%s not found", inpNormal.Source)
  317. }
  318. // Get normals source float array
  319. normArray, ok = source.ArrayElement.(*FloatArray)
  320. if !ok {
  321. return nil, 0, fmt.Errorf("NORMAL source:%s not float array", inpNormal.Source)
  322. }
  323. }
  324. // Get optional TEXCOORD input
  325. inpTexcoord := getInputSemantic(tr.Input, "TEXCOORD")
  326. var texArray *FloatArray
  327. if inpTexcoord != nil {
  328. // Get texture coordinates source
  329. source := getMeshSource(m, inpTexcoord.Source)
  330. if source == nil {
  331. return nil, 0, fmt.Errorf("TEXCOORD source:%s not found", inpTexcoord.Source)
  332. }
  333. // Get texture coordinates source float array
  334. texArray, ok = source.ArrayElement.(*FloatArray)
  335. if !ok {
  336. return nil, 0, fmt.Errorf("TEXCOORD source:%s not float array", inpTexcoord.Source)
  337. }
  338. }
  339. // Initialize geometry group
  340. groupStart := indices.Size()
  341. // For each primitive index
  342. inputCount := len(tr.Input)
  343. for i := 0; i < len(tr.P); i += inputCount {
  344. // Vertex attributes: position(3) + normal(3) + uv(2)
  345. var vx [8]float32
  346. // Vertex position
  347. posIndex := tr.P[i+inpVertex.Offset] * 3
  348. // Get position vector and appends to its buffer
  349. vx[0] = posArray.Data[posIndex]
  350. vx[1] = posArray.Data[posIndex+1]
  351. vx[2] = posArray.Data[posIndex+2]
  352. // Optional vertex normal
  353. if inpNormal != nil {
  354. // Get normal index from P
  355. normIndex := tr.P[i+inpNormal.Offset] * 3
  356. // Get normal vector and appends to its buffer
  357. vx[3] = normArray.Data[normIndex]
  358. vx[4] = normArray.Data[normIndex+1]
  359. vx[5] = normArray.Data[normIndex+2]
  360. }
  361. // Optional vertex texture coordinate
  362. if inpTexcoord != nil {
  363. // Get normal index from P
  364. texIndex := tr.P[i+inpTexcoord.Offset] * 2
  365. // Get normal vector and appends to its buffer
  366. vx[6] = texArray.Data[texIndex]
  367. vx[7] = texArray.Data[texIndex+1]
  368. }
  369. // If this vertex and its attributes has already been appended,
  370. // reuse it, adding its index to the index buffer
  371. // to reuse its index
  372. idx, ok := mVindex[vx]
  373. if ok {
  374. indices.Append(idx)
  375. continue
  376. }
  377. // Appends new vertex position and attributes to its buffers
  378. positions.Append(vx[0], vx[1], vx[2])
  379. if inpNormal != nil {
  380. normals.Append(vx[3], vx[4], vx[5])
  381. }
  382. if inpTexcoord != nil {
  383. uvs.Append(vx[6], vx[7])
  384. }
  385. indices.Append(index)
  386. // Save the index to this vertex position and attributes for
  387. // future reuse
  388. mVindex[vx] = index
  389. index++
  390. }
  391. // Adds this geometry group to the list
  392. geomGroups = append(geomGroups, geometry.Group{
  393. Start: groupStart,
  394. Count: indices.Size() - groupStart,
  395. Matindex: groupMatindex,
  396. Matid: tr.Material,
  397. })
  398. // Debug dump
  399. //for i := 0; i < positions.Size()/3; i++ {
  400. // vidx := i*3
  401. // msg := fmt.Sprintf("i:%2d position:%v %v %v",
  402. // i, positions.Get(vidx), positions.Get(vidx+1), positions.Get(vidx+2))
  403. // if normals.Size() > 0 {
  404. // msg += fmt.Sprintf("\tnormal:%v %v %v",
  405. // normals.Get(vidx), normals.Get(vidx+1), normals.Get(vidx+2))
  406. // }
  407. // if uvs.Size() > 0 {
  408. // msg += fmt.Sprintf("\tuv:%v %v", uvs.Get(i*2), uvs.Get(i*2+1))
  409. // }
  410. // log.Debug("%s", msg)
  411. //}
  412. //log.Debug("indices(%d):%v", indices.Size(), indices)
  413. //log.Debug("groups:%v", geomGroups)
  414. // Creates geometry
  415. geom := geometry.NewGeometry()
  416. // Creates VBO with vertex positions
  417. geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  418. // Creates VBO with vertex normals
  419. if normals.Size() > 0 {
  420. geom.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
  421. }
  422. // Creates VBO with uv coordinates
  423. if uvs.Size() > 0 {
  424. geom.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
  425. }
  426. // Sets the geometry indices buffer
  427. geom.SetIndices(indices)
  428. // Add material groups to the geometry
  429. geom.AddGroupList(geomGroups)
  430. return geom, gls.TRIANGLES, nil
  431. }
  432. func newMeshLines(m *Mesh, ln *Lines) (*geometry.Geometry, uint32, error) {
  433. if ln.Input == nil || len(ln.Input) == 0 {
  434. return nil, 0, fmt.Errorf("No inputs in lines")
  435. }
  436. // Get vertices positions
  437. if len(m.Vertices.Input) != 1 {
  438. return nil, 0, fmt.Errorf("Mesh.Vertices.Input length not supported")
  439. }
  440. vinp := m.Vertices.Input[0]
  441. if vinp.Semantic != "POSITION" {
  442. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Semantic:%s not supported", vinp.Semantic)
  443. }
  444. // Get vertices input source
  445. inps := getMeshSource(m, vinp.Source)
  446. if inps == nil {
  447. return nil, 0, fmt.Errorf("Source:%s not found", vinp.Source)
  448. }
  449. // Get vertices input float array
  450. // Ignore Accessor (??)
  451. posArray, ok := inps.ArrayElement.(*FloatArray)
  452. if !ok {
  453. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Source not FloatArray")
  454. }
  455. // Get VERTEX input
  456. inpVertex := getInputSemantic(ln.Input, "VERTEX")
  457. if inpVertex == nil {
  458. return nil, 0, fmt.Errorf("VERTEX input not found")
  459. }
  460. // Creates buffers
  461. positions := math32.NewArrayF32(0, 0)
  462. indices := math32.NewArrayU32(0, 0)
  463. mVindex := make(map[[3]float32]uint32)
  464. inputCount := len(ln.Input)
  465. var index uint32
  466. for i := 0; i < len(ln.P); i += inputCount {
  467. // Vertex position
  468. var vx [3]float32
  469. // Get position index from P
  470. posIndex := ln.P[i+inpVertex.Offset] * 3
  471. // Get position vector and appends to its buffer
  472. vx[0] = posArray.Data[posIndex]
  473. vx[1] = posArray.Data[posIndex+1]
  474. vx[2] = posArray.Data[posIndex+2]
  475. // If this vertex and its attributes has already been appended,
  476. // reuse it, adding its index to the index buffer
  477. // to reuse its index
  478. idx, ok := mVindex[vx]
  479. if ok {
  480. indices.Append(idx)
  481. continue
  482. }
  483. // Appends new vertex position and attributes to its buffers
  484. positions.Append(vx[0], vx[1], vx[2])
  485. indices.Append(index)
  486. // Save the index to this vertex position and attributes for
  487. // future reuse
  488. //mVindex[vx] = index
  489. index++
  490. }
  491. // Creates geometry
  492. geom := geometry.NewGeometry()
  493. // Creates VBO with vertex positions
  494. geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  495. // Sets the geometry indices buffer
  496. geom.SetIndices(indices)
  497. return geom, gls.LINES, nil
  498. }
  499. func newMeshLineStrips(m *Mesh, ls *LineStrips) (*geometry.Geometry, uint32, error) {
  500. return nil, 0, fmt.Errorf("not implemented yet")
  501. }
  502. func newMeshTrifans(m *Mesh, ls *Trifans) (*geometry.Geometry, uint32, error) {
  503. return nil, 0, fmt.Errorf("not implemented yet")
  504. }
  505. func newMeshTristrips(m *Mesh, ls *Tristrips) (*geometry.Geometry, uint32, error) {
  506. return nil, 0, fmt.Errorf("not implemented yet")
  507. }
  508. // Creates and returns pointer to a new geometry for POINTS
  509. func newMeshPoints(m *Mesh) (*geometry.Geometry, uint32, error) {
  510. // Get vertices positions
  511. if len(m.Vertices.Input) != 1 {
  512. return nil, 0, fmt.Errorf("Mesh.Vertices.Input length not supported")
  513. }
  514. vinp := m.Vertices.Input[0]
  515. if vinp.Semantic != "POSITION" {
  516. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Semantic:%s not supported", vinp.Semantic)
  517. }
  518. // Get vertices input source
  519. inps := getMeshSource(m, vinp.Source)
  520. if inps == nil {
  521. return nil, 0, fmt.Errorf("Source:%s not found", vinp.Source)
  522. }
  523. // Get vertices input float array
  524. // Ignore Accessor (??)
  525. posArray, ok := inps.ArrayElement.(*FloatArray)
  526. if !ok {
  527. return nil, 0, fmt.Errorf("Mesh.Vertices.Input.Source not FloatArray")
  528. }
  529. // Creates buffer and copy data
  530. positions := math32.NewArrayF32(posArray.Count, posArray.Count)
  531. //positions.CopyFrom(posArray.Data)
  532. copy(positions, posArray.Data)
  533. // Creates geometry and add VBO with vertex positions
  534. geom := geometry.NewGeometry()
  535. geom.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  536. return geom, gls.POINTS, nil
  537. }
  538. func getMeshSource(m *Mesh, uri string) *Source {
  539. id := strings.TrimPrefix(uri, "#")
  540. for _, s := range m.Source {
  541. if s.Id == id {
  542. return s
  543. }
  544. }
  545. return nil
  546. }
  547. func getInputSemantic(inps []InputShared, semantic string) *InputShared {
  548. for i := 0; i < len(inps); i++ {
  549. if inps[i].Semantic == semantic {
  550. return &inps[i]
  551. }
  552. }
  553. return nil
  554. }