monument-app.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. if (typeof AFRAME === 'undefined') {
  2. throw new Error('Component attempted to register before AFRAME was available.');
  3. }
  4. AFRAME.registerComponent('gizmo', {
  5. schema: {
  6. mode: { default: 'translate' }
  7. },
  8. update: function (old) {
  9. let modes = ['translate', 'rotate', 'scale'];
  10. if (!this.gizmo) {
  11. let newMode = modes.filter(el => {
  12. return el == this.data.mode
  13. })
  14. if (newMode.length !== 0) {
  15. this.mode = this.data.mode
  16. this.transformControls.setMode(this.mode)
  17. }
  18. }
  19. },
  20. init: function () {
  21. let self = this
  22. this.mode = this.data.mode
  23. let activeCamera = document.querySelector('#avatarControl').getObject3D('camera');
  24. let renderer = this.el.sceneEl.renderer;
  25. this.transformControls = new THREE.TransformControls(activeCamera, renderer.domElement);
  26. this.transformControls.attach( this.el.object3D);
  27. this.el.sceneEl.setObject3D('control-'+this.el.id, this.transformControls);
  28. this.transformControls.addEventListener('change', function (evt) {
  29. // console.log('changed');
  30. var object = self.transformControls.object;
  31. if (object === undefined) {
  32. return;
  33. }
  34. var transformMode = self.transformControls.getMode();
  35. switch (transformMode) {
  36. case 'translate':
  37. vwf_view.kernel.setProperty(object.el.id, 'position',
  38. [object.position.x, object.position.y, object.position.z] )
  39. break;
  40. case 'rotate':
  41. vwf_view.kernel.setProperty(object.el.id, 'rotation',
  42. [THREE.Math.radToDeg(object.rotation.x), THREE.Math.radToDeg(object.rotation.y), THREE.Math.radToDeg(object.rotation.z)] )
  43. break;
  44. case 'scale':
  45. vwf_view.kernel.setProperty(object.el.id, 'scale',
  46. [object.scale.x, object.scale.y, object.scale.z] )
  47. break;
  48. }
  49. //vwf_view.kernel.fireEvent(evt.detail.target.id, "clickEvent")
  50. });
  51. },
  52. remove: function () {
  53. this.transformControls.detach();
  54. this.el.sceneEl.removeObject3D('control-'+this.el.id);
  55. },
  56. tick: function (t) {
  57. this.transformControls.update();
  58. }
  59. });
  60. AFRAME.registerComponent('cursor-listener', {
  61. init: function () {
  62. this.el.addEventListener('click', function (evt) {
  63. console.log('I was clicked at: ', evt.detail.intersection.point);
  64. let cursorID = 'cursor-avatar-'+ vwf_view.kernel.moniker();
  65. if (evt.detail.cursorEl.id.includes(vwf_view.kernel.moniker())) {
  66. vwf_view.kernel.fireEvent(evt.detail.target.id, "clickEvent")
  67. }
  68. //vwf_view.kernel.fireEvent(evt.detail.target.id, "clickEvent")
  69. });
  70. }
  71. });
  72. AFRAME.registerComponent('raycaster-listener', {
  73. init: function () {
  74. let self = this;
  75. this.intersected = false;
  76. this.casters = {}
  77. this.el.addEventListener('raycaster-intersected', function (evt) {
  78. if (evt.detail.el.nodeName == 'A-CURSOR') {
  79. //console.log('CURSOR was intersected at: ', evt.detail.intersection.point);
  80. } else {
  81. if (self.intersected) {
  82. } else {
  83. console.log('I was intersected at: ', evt.detail.intersection.point);
  84. vwf_view.kernel.fireEvent(evt.detail.target.id, "intersectEvent")
  85. }
  86. self.casters[evt.detail.el.id] = evt.detail.el;
  87. self.intersected = true;
  88. }
  89. });
  90. this.el.addEventListener('raycaster-intersected-cleared', function (evt) {
  91. if (evt.detail.el.nodeName == 'A-CURSOR') {
  92. //console.log('CURSOR was intersected at: ', evt.detail.intersection.point);
  93. } else {
  94. if (self.intersected) {
  95. console.log('Clear intersection');
  96. if (Object.entries(self.casters).length == 1 && (self.casters[evt.detail.el.id] !== undefined))
  97. {
  98. vwf_view.kernel.fireEvent(evt.detail.target.id, "clearIntersectEvent")
  99. }
  100. delete self.casters[evt.detail.el.id]
  101. } else {}
  102. self.intersected = false;
  103. }
  104. });
  105. }
  106. });
  107. AFRAME.registerComponent('envmap', {
  108. /**
  109. * Creates a new THREE.ShaderMaterial using the two shaders defined
  110. * in vertex.glsl and fragment.glsl.
  111. */
  112. init: function () {
  113. const data = this.data;
  114. //this.applyToMesh();
  115. this.el.addEventListener('model-loaded', () => this.applyToMesh());
  116. },
  117. /**
  118. * Update the ShaderMaterial when component data changes.
  119. */
  120. update: function () {
  121. },
  122. getEnvMap: function () {
  123. var path = './assets/textures/skybox2/';
  124. var format = '.jpg';
  125. var urls = [
  126. path + 'px' + format, path + 'nx' + format,
  127. path + 'py' + format, path + 'ny' + format,
  128. path + 'pz' + format, path + 'nz' + format
  129. ];
  130. envMap = new THREE.CubeTextureLoader().load(urls);
  131. envMap.format = THREE.RGBFormat;
  132. return envMap;
  133. },
  134. /**
  135. * Apply the material to the current entity.
  136. */
  137. applyToMesh: function () {
  138. const mesh = this.el.getObject3D('mesh');
  139. //var scene = mesh;
  140. var envMap = this.getEnvMap();
  141. mesh.traverse(function (node) {
  142. if (node.material) {
  143. node.material.side = THREE.BackSide;
  144. node.material.needsUpdate = true;
  145. //side = THREE.DoubleSide; break;
  146. }
  147. });
  148. mesh.traverse(function (node) {
  149. if (node.material && (node.material.isMeshStandardMaterial ||
  150. (node.material.isShaderMaterial && node.material.envMap !== undefined))) {
  151. node.material.envMap = envMap;
  152. node.material.needsUpdate = true;
  153. }
  154. });
  155. // const mesh = this.el.getObject3D('mesh');
  156. // if (mesh) {
  157. // mesh.material = this.material;
  158. // }
  159. },
  160. /**
  161. * On each frame, update the 'time' uniform in the shaders.
  162. */
  163. tick: function (t) {
  164. }
  165. })
  166. //https://threejs.org/examples/webgl_shaders_sky.html
  167. AFRAME.registerComponent('skyshader', {
  168. init: function () {
  169. let sunSphereEl = document.querySelector('a-scene').querySelector('#sun');
  170. this.sunSphere = sunSphereEl.object3D;
  171. this.sky = new THREE.Sky();
  172. let scene = this.el.sceneEl;
  173. let effectController = {
  174. turbidity: 5,
  175. rayleigh: 2,
  176. mieCoefficient: 0.005,
  177. mieDirectionalG: 0.8,
  178. luminance: 1,
  179. inclination: 0, // elevation / inclination
  180. azimuth: 0.25, // Facing front,
  181. sun: ! true
  182. };
  183. let uniforms = this.sky.uniforms;
  184. uniforms.turbidity.value = effectController.turbidity;
  185. uniforms.rayleigh.value = effectController.rayleigh;
  186. uniforms.luminance.value = effectController.luminance;
  187. uniforms.mieCoefficient.value = effectController.mieCoefficient;
  188. uniforms.mieDirectionalG.value = effectController.mieDirectionalG;
  189. this.el.setObject3D('mesh', this.sky.mesh);
  190. let distance = 400000;
  191. var theta = Math.PI * (effectController.inclination - 0.5);
  192. var phi = 2 * Math.PI * (effectController.azimuth - 0.5);
  193. this.sunSphere.position.x = distance * Math.cos(phi);
  194. this.sunSphere.position.y = distance * Math.sin(phi) * Math.sin(theta);
  195. this.sunSphere.position.z = distance * Math.sin(phi) * Math.cos(theta);
  196. this.sunSphere.visible = effectController.sun;
  197. this.sky.uniforms.sunPosition.value.copy(this.sunSphere.position);
  198. },
  199. update: function () {
  200. },
  201. tick: function (t) {
  202. }
  203. })
  204. AFRAME.registerComponent('sun', {
  205. init: function () {
  206. this.sunSphere = new THREE.Mesh(
  207. new THREE.SphereBufferGeometry(20000, 16, 8),
  208. new THREE.MeshBasicMaterial({ color: 0xffffff })
  209. );
  210. this.sunSphere.position.y = - 700000;
  211. this.sunSphere.visible = true;
  212. this.el.setObject3D('mesh', this.sunSphere);
  213. },
  214. update: function () {
  215. },
  216. tick: function (t) {
  217. }
  218. })
  219. AFRAME.registerComponent('avatarbvh0', {
  220. /**
  221. * Creates a new THREE.ShaderMaterial using the two shaders defined
  222. * in vertex.glsl and fragment.glsl.
  223. */
  224. init: function () {
  225. let skeletonHelper;
  226. let self = this;
  227. this.clock = new THREE.Clock();
  228. let loader = new THREE.BVHLoader();
  229. loader.load("./assets/walk.bvh", function (result) {
  230. skeletonHelper = new THREE.SkeletonHelper(result.skeleton.bones[0]);
  231. skeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to SkeletonHelper directly
  232. //var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors, depthTest: false, depthWrite: false, transparent: true } );
  233. skeletonHelper.material.depthTest = true;
  234. skeletonHelper.material.lineWidth = 10.0;
  235. skeletonHelper.material.depthWrite = true;
  236. skeletonHelper.material.transparent = false;
  237. skeletonHelper.material.flatShading = true;
  238. var boneContainer = new THREE.Group();
  239. boneContainer.add(result.skeleton.bones[0]);
  240. self.el.setObject3D('skeletonHelper', skeletonHelper);
  241. self.el.setObject3D('mesh', boneContainer);
  242. //scene.add( skeletonHelper );
  243. // scene.add( boneContainer );
  244. // play animation
  245. self.mixer = new THREE.AnimationMixer(skeletonHelper);
  246. self.mixer.clipAction(result.clip).setEffectiveWeight(1.0).play();
  247. });
  248. },
  249. /**
  250. * Update the ShaderMaterial when component data changes.
  251. */
  252. update: function () {
  253. },
  254. tick: function (t) {
  255. var delta = this.clock.getDelta();
  256. if (this.mixer) this.mixer.update(delta);
  257. }
  258. })
  259. AFRAME.registerComponent('avatarbvh', {
  260. init: function () {
  261. let helper;
  262. let self = this;
  263. this.clock = new THREE.Clock();
  264. console.log(this.el.object3D);
  265. this.el.addEventListener('model-loaded', function (evt) {
  266. const model = evt.detail.model
  267. console.log(model);
  268. // let loader = new THREE.BVHLoader();
  269. // loader.load("./assets/walk.bvh", function (bvh) {
  270. // console.log(model);
  271. // self.mixer = new THREE.AnimationMixer(model.children[0].children[0]);
  272. // self.mixer.clipAction(bvh.clip).setEffectiveWeight(1.0).play();
  273. // })
  274. //console.log(evt);
  275. self.mixer = new THREE.AnimationMixer(model);
  276. self.mixer.clipAction(model.animations[0]).setEffectiveWeight(1.0).play();
  277. })
  278. let loader = new THREE.BVHLoader();
  279. loader.load("./assets/walk.bvh", function (bvh) {
  280. const mesh = self.el.object3D;
  281. //mesh.material.skinning = true;
  282. // mesh.updateMatrixWorld();
  283. // mesh.skeleton.calculateInverses();
  284. // mesh.normalizeSkinWeights ()
  285. // See example from THREE.Skeleton for the armSkeleton
  286. // var rootBone = bvh.skeleton.bones[0]
  287. // mesh.add( rootBone );
  288. // mesh.bind( bvh.skeleton );
  289. // skeletonHelper = new THREE.SkeletonHelper(mesh);
  290. // self.mixer = new THREE.AnimationMixer(mesh );
  291. // self.mixer.clipAction(bvh.clip).setEffectiveWeight(1.0).play();
  292. })
  293. },
  294. update: function () {
  295. },
  296. tick: function (t) {
  297. var delta = this.clock.getDelta();
  298. // update skeletal animcation
  299. if (this.mixer){
  300. this.mixer.update(delta)
  301. }
  302. }
  303. })
  304. AFRAME.registerComponent('avatarbvh_best', {
  305. /**
  306. * Creates a new THREE.ShaderMaterial using the two shaders defined
  307. * in vertex.glsl and fragment.glsl.
  308. */
  309. createBones: function (object, jsonBones) {
  310. /* adapted from the THREE.SkinnedMesh constructor */
  311. // create bone instances from json bone data
  312. const bones = jsonBones.map(gbone => {
  313. bone = new THREE.Bone()
  314. bone.name = gbone.name
  315. bone.position.fromArray(gbone.pos)
  316. bone.quaternion.fromArray(gbone.rotq)
  317. if (gbone.scl !== undefined) bone.scale.fromArray(gbone.scl)
  318. return bone
  319. })
  320. // add bone instances to the root object
  321. jsonBones.forEach((gbone, index) => {
  322. if (gbone.parent !== -1 && gbone.parent !== null && bones[gbone.parent] !== undefined) {
  323. bones[gbone.parent].add(bones[index])
  324. } else {
  325. // object.add(bones[index])
  326. }
  327. })
  328. return bones
  329. },
  330. createSkinnedMesh: function (mesh, skeleton) {
  331. // create SkinnedMesh from static mesh geometry and swap it in the scene graph
  332. const skinnedMesh = new THREE.SkinnedMesh(mesh.geometry, mesh.material)
  333. skinnedMesh.castShadow = true
  334. skinnedMesh.receiveShadow = true
  335. // bind to skeleton
  336. skinnedMesh.bind(skeleton)
  337. // swap mesh for skinned mesh
  338. //mesh.parent.add(skinnedMesh)
  339. // mesh.parent.remove(mesh)
  340. return skinnedMesh
  341. },
  342. init: function () {
  343. let helper;
  344. let self = this;
  345. this.clock = new THREE.Clock();
  346. let loader = new THREE.BVHLoader();
  347. loader.load("./assets/walk.bvh", function (bvh) {
  348. // skeletonHelper = new THREE.SkeletonHelper(result.skeleton.bones[0]);
  349. // skeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to SkeletonHelper directly
  350. self.bvhData = bvh;
  351. new THREE.GLTFLoader().load("./assets/av2/avatar.gltf", result => {
  352. let scene = result
  353. const mesh = new THREE.SkinnedMesh(
  354. result,
  355. new THREE.MeshPhongMaterial()
  356. );
  357. mesh.material.skinning = true;
  358. //group.add( mesh );
  359. mesh.updateMatrixWorld();
  360. mesh.skeleton.calculateInverses();
  361. mesh.normalizeSkinWeights ()
  362. // See example from THREE.Skeleton for the armSkeleton
  363. var rootBone = self.bvhData.skeleton.bones[0]
  364. mesh.add( rootBone );
  365. // Bind the skeleton to the mesh
  366. mesh.bind( self.bvhData.skeleton );
  367. skeletonHelper = new THREE.SkeletonHelper(mesh);
  368. //skeletonHelper.skeleton = self.bvhData.skeleton;
  369. //var boneContainer = new THREE.Group();
  370. // boneContainer.add(mesh);
  371. // mesh.bind(self.bvhData.skeleton, mesh.matrixWorld)
  372. // const bones = self.createBones(result, result.bones)
  373. // mesh.updateMatrixWorld()
  374. // let skeleton = new THREE.Skeleton(bones, undefined, true)
  375. // mesh.bind(skeleton, mesh.matrixWorld)
  376. // let body = self.createSkinnedMesh(mesh, skeleton)
  377. // skeletonHelper = new THREE.SkeletonHelper(body);
  378. self.el.setObject3D('mesh', mesh)
  379. //self.el.setObject3D('mesh',boneContainer)
  380. self.mixer = new THREE.AnimationMixer(mesh );
  381. self.mixer.clipAction(self.bvhData.clip).setEffectiveWeight(1.0).play();
  382. //self.mixer.clipAction( mesh.geometry.animations[ 0 ] ).play();
  383. // const mesh = new THREE.SkinnedMesh(
  384. // result,
  385. // new THREE.MeshPhongMaterial()
  386. // );
  387. // mesh.material.skinning = true;
  388. // self.el.setObject3D('mesh', mesh)
  389. // self.mixer = new THREE.AnimationMixer( mesh );
  390. // self.mixer.clipAction( mesh.geometry.animations[ 0 ] ).play();
  391. // find armature root object.
  392. // This is a group instance with a userData.bones property
  393. // containing bones in the same format as would normally be
  394. // found on a SkinnedMesh Geometry instance
  395. //let root = scene.getObjectByName('Human')
  396. // manually create bones and parent them to the root object
  397. // NOTE: This is normally done in the SkinnedMesh constructor
  398. // const bones = self.createBones(root, root.userData.bones)
  399. // const bones = bvh.skeleton.bones[0]
  400. // Important! must update world matrices before creating skeleton instance
  401. //result.updateMatrixWorld()
  402. // create skeleton
  403. // let skeleton = new THREE.Skeleton(bones, undefined, true)
  404. // const skinnedMesh = new THREE.SkinnedMesh(result, null)
  405. // skinnedMesh.bind(skeleton, mesh.matrixWorld)
  406. // create SkinnedMesh from static mesh geometry
  407. // let body = self.createSkinnedMesh(root.getObjectByName('Body'), skeleton)
  408. //let body = self.createSkinnedMesh(result, skeleton)
  409. //let clothes = self.createSkinnedMesh(root.getObjectByName('Clothes'), skeleton)
  410. // create skeleton helper
  411. // self.helper = new THREE.SkeletonHelper(root)
  412. // scene.add(self.helper)
  413. // self.el.setObject3D('mesh', scene)
  414. // self.el.setObject3D('mesh', clothes)
  415. //self.el.setObject3D('skeletonHelper', self.helper)
  416. // scene.add( helper )
  417. // skeletal animation
  418. // self.mixer = new THREE.AnimationMixer(root);
  419. //self.mixer.clipAction(scene.animations[0]).play()
  420. // self.mixer.clipAction(bvh.clip).setEffectiveWeight(1.0).play();
  421. // let action = self.mixer.clipAction( scene.animations[ 0 ] ).play();
  422. //action.enabled = true;
  423. // self.mixer = new THREE.AnimationMixer(self.helper);
  424. // self.mixer.clipAction(scene.animations[0]).play();
  425. // start
  426. //animate()
  427. })
  428. })
  429. },
  430. /**
  431. * Update the ShaderMaterial when component data changes.
  432. */
  433. update: function () {
  434. },
  435. tick: function (t) {
  436. var delta = this.clock.getDelta();
  437. // update skeletal animcation
  438. if (this.mixer){
  439. this.mixer.update(delta)
  440. // update skeleton helper
  441. //this.helper.update()
  442. }
  443. }
  444. })