export almost works
This commit is contained in:
parent
a456cd8264
commit
29ad07eabd
5 changed files with 129 additions and 17 deletions
|
|
@ -11,6 +11,7 @@ import { MTLLoader } from 'super-three/examples/jsm/loaders/MTLLoader';
|
||||||
import * as BufferGeometryUtils from 'super-three/examples/jsm/utils/BufferGeometryUtils';
|
import * as BufferGeometryUtils from 'super-three/examples/jsm/utils/BufferGeometryUtils';
|
||||||
import { LightProbeGenerator } from 'super-three/examples/jsm/lights/LightProbeGenerator';
|
import { LightProbeGenerator } from 'super-three/examples/jsm/lights/LightProbeGenerator';
|
||||||
import { TransformControls } from 'super-three/examples/jsm/controls/TransformControls.js';
|
import { TransformControls } from 'super-three/examples/jsm/controls/TransformControls.js';
|
||||||
|
import { GLTFExporter } from 'super-three/examples/jsm/exporters/GLTFExporter.js';
|
||||||
|
|
||||||
var THREE = window.THREE = SUPER_THREE;
|
var THREE = window.THREE = SUPER_THREE;
|
||||||
|
|
||||||
|
|
@ -28,6 +29,7 @@ THREE.OBB = OBB;
|
||||||
THREE.BufferGeometryUtils = BufferGeometryUtils;
|
THREE.BufferGeometryUtils = BufferGeometryUtils;
|
||||||
THREE.LightProbeGenerator = LightProbeGenerator;
|
THREE.LightProbeGenerator = LightProbeGenerator;
|
||||||
THREE.TransformControls = TransformControls;
|
THREE.TransformControls = TransformControls;
|
||||||
|
THREE.GLTFExporter = GLTFExporter;
|
||||||
//THREE.Text = Text
|
//THREE.Text = Text
|
||||||
|
|
||||||
export default THREE;
|
export default THREE;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,62 @@
|
||||||
// reactive component for displaying the menu
|
// reactive component for displaying the menu
|
||||||
|
|
||||||
|
$editorPopup = (el) => new Proxy({
|
||||||
|
|
||||||
|
html: (opts) => `
|
||||||
|
<div>
|
||||||
|
<b>#${$editor.selected.name}</b>
|
||||||
|
<table class="editorPopup">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><b class="badge">href</a></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="href" placeholder="https://foo.com" maxlength="255"
|
||||||
|
onkeyup="$editor.selected.edited = $editor.selected.userData.href = this.value"
|
||||||
|
value="${$editor.selected.userData.href||''}" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b class="badge">src</a></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="src" placeholder="https://foo.com" maxlength="255"
|
||||||
|
onkeyup="$editor.selected.edited = $editor.selected.userData.src = this.value"
|
||||||
|
value="${$editor.selected.userData.src||''}" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b class="badge">tag</a></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="tag" placeholder="foo bar" maxlength="255"
|
||||||
|
onkeyup="$editor.selected.edited = $editor.selected.userData.tag = this.value"
|
||||||
|
value="${$editor.selected.userData.tag||''}" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<style type="text/css">
|
||||||
|
table.editorPopup input{
|
||||||
|
min-width:200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`,
|
||||||
|
|
||||||
|
init(opts){
|
||||||
|
el.innerHTML = this.html(opts)
|
||||||
|
return el
|
||||||
|
},
|
||||||
|
|
||||||
|
},{
|
||||||
|
|
||||||
|
get(me,k,v){ return me[k] },
|
||||||
|
|
||||||
|
set(me,k,v){
|
||||||
|
me[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
$editor = (el,opts) => new Proxy({
|
$editor = (el,opts) => new Proxy({
|
||||||
|
|
||||||
html: `
|
html: `
|
||||||
|
|
@ -13,6 +71,10 @@ $editor = (el,opts) => new Proxy({
|
||||||
width: 30px;
|
width: 30px;
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
}
|
}
|
||||||
|
.edit-btn.enabled,
|
||||||
|
.edit-btn.enabled:hover{
|
||||||
|
background:black;
|
||||||
|
}
|
||||||
.edit-btn i.gg-pen{
|
.edit-btn i.gg-pen{
|
||||||
margin-top: -26px;
|
margin-top: -26px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
|
@ -30,23 +92,26 @@ $editor = (el,opts) => new Proxy({
|
||||||
el.innerHTML = this.html
|
el.innerHTML = this.html
|
||||||
window.frontend.el.querySelector('#topbar').appendChild(el);
|
window.frontend.el.querySelector('#topbar').appendChild(el);
|
||||||
el.querySelector('.edit-btn').addEventListener('click', () => $editor.enabled = true )
|
el.querySelector('.edit-btn').addEventListener('click', () => $editor.enabled = true )
|
||||||
|
|
||||||
|
document.addEventListener('download', (e) => this.updateOriginalScene(e.detail) )
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
editNode(){
|
editNode(){
|
||||||
if( !this.enabled ) return console.log("not editing")
|
if( !this.enabled ) return console.log("not editing")
|
||||||
console.log("click!")
|
$editor.enabled = false // disable selections
|
||||||
$editor.enabled = false // disable selections
|
|
||||||
this.enableHref(this.selected,true) // re-enable hrefs
|
this.enableHref(this.selected,true) // re-enable hrefs
|
||||||
notify(`${this.selected.name}<br>${this.getMetaData(this.selected)}`)
|
//`<b>XR Fragment:</b> #${this.selected.name}<br><br>${this.getMetaData(this.selected)}`),{
|
||||||
notify(`<b>XR Fragment:</b> #${this.selected.name}<br><br>${this.getMetaData(this.selected)}`)
|
notify( $editorPopup( document.createElement('div') ).init(this) , {
|
||||||
|
timeout:false,
|
||||||
|
onclose: () => xrf.scene.remove( this.helper )
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
initEdit(scene){
|
initEdit(scene){
|
||||||
AFRAME.scenes[0].addEventListener('click', () => this.editNode() )
|
AFRAME.scenes[0].addEventListener('click', () => this.editNode() )
|
||||||
scene.traverse( (n) => {
|
scene.traverse( (n) => {
|
||||||
let highlight = (n) => (e) => {
|
let highlight = (n) => (e) => {
|
||||||
console.log(n.name)
|
|
||||||
if( this.selected ) this.enableHref(this.selected,true) // re-enable href of previous selection
|
if( this.selected ) this.enableHref(this.selected,true) // re-enable href of previous selection
|
||||||
if( this.helper){
|
if( this.helper){
|
||||||
if( this.helper.selected == n.uuid ) return // already selected
|
if( this.helper.selected == n.uuid ) return // already selected
|
||||||
|
|
@ -62,17 +127,20 @@ $editor = (el,opts) => new Proxy({
|
||||||
xrf.scene.add(this.helper)
|
xrf.scene.add(this.helper)
|
||||||
|
|
||||||
let div = document.createElement('div')
|
let div = document.createElement('div')
|
||||||
notify(`<b>XR Fragment:</b> #${n.name}<br><br>${this.getMetaData(this.selected)}`)
|
notify(`<b>#${n.name}</b><br>${this.getMetaData(this.selected)}`)
|
||||||
|
|
||||||
this.enableHref(n,false) // prevent clicks from doing their usual teleporting/executions
|
this.enableHref(n,false) // prevent clicks from doing their usual teleporting/executions
|
||||||
}
|
}
|
||||||
if( n.geometry ) n.addEventListener('mousemove', n.highlightOnMouseMove = highlight(n) )
|
if( n.material ) n.addEventListener('mousemove', n.highlightOnMouseMove = highlight(n) )
|
||||||
})
|
})
|
||||||
console.log("inited scene")
|
console.log("inited scene")
|
||||||
},
|
},
|
||||||
|
|
||||||
getMetaData(n){
|
getMetaData(n){
|
||||||
return `href: ${n.userData.href}<br>src: ${n.userData.src}<br>tag: ${n.userData.tag}`
|
let html = `${n.userData.href ? `<b class="badge">href</b>${n.userData.href}<br>`:''}`
|
||||||
|
html += `${n.userData.src ? `<b class="badge">src</b>${n.userData.src}<br>` :''}`
|
||||||
|
html += `${n.userData.tag ? `<b class="badge">tag</b>${n.userData.tag}<br>` :''}`
|
||||||
|
return html
|
||||||
},
|
},
|
||||||
|
|
||||||
enableHref(n, state){
|
enableHref(n, state){
|
||||||
|
|
@ -86,6 +154,15 @@ $editor = (el,opts) => new Proxy({
|
||||||
n.userData.XRF.href.exec = exec.bak
|
n.userData.XRF.href.exec = exec.bak
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateOriginalScene(opts){
|
||||||
|
let {scene,ext} = opts
|
||||||
|
xrf.scene.traverse( (n) => {
|
||||||
|
if( n.edited && scene.getObjectByName(n.name) ){
|
||||||
|
scene.getObjectByName(n.name).userData = n.userData
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -98,20 +175,25 @@ $editor = (el,opts) => new Proxy({
|
||||||
switch( k ){
|
switch( k ){
|
||||||
|
|
||||||
case "enabled":{
|
case "enabled":{
|
||||||
|
lookctl = $('[look-controls]').components['look-controls']
|
||||||
if( v ){
|
if( v ){
|
||||||
|
lookctl.pause() // prevent click-conflict
|
||||||
notify("click an object to reveal XR Fragment metadata")
|
notify("click an object to reveal XR Fragment metadata")
|
||||||
xrf.interactive.raycastAll = true
|
xrf.interactive.raycastAll = true
|
||||||
if( !xrf.scene.initEdit ) me.initEdit(xrf.scene)
|
if( !xrf.scene.initEdit ) me.initEdit(xrf.scene)
|
||||||
|
|
||||||
|
lookctl.pause() // prevent click-conflict
|
||||||
|
el.querySelector('.edit-btn').classList.add(['enabled'])
|
||||||
}else{
|
}else{
|
||||||
console.log("idsabled")
|
lookctl.pause() // prevent click-conflict
|
||||||
xrf.scene.traverse( (n) => {
|
xrf.scene.traverse( (n) => {
|
||||||
me.enableHref(n,true)
|
me.enableHref(n,true)
|
||||||
if( n.highlightOnMouseMove ){
|
if( n.highlightOnMouseMove ){
|
||||||
n.removeEventListener( 'mousemove', n.highlightOnMouseMove )
|
n.removeEventListener( 'mousemove', n.highlightOnMouseMove )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
me.helper.remove()
|
lookctl.play() // prevent click-conflict (resume)
|
||||||
console.log("removed events")
|
el.querySelector('.edit-btn').classList.remove(['enabled'])
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,15 +239,38 @@ window.frontend = (opts) => new Proxy({
|
||||||
},
|
},
|
||||||
|
|
||||||
download(){
|
download(){
|
||||||
function fetchAndDownload(dataurl, filename) {
|
// setup exporters
|
||||||
|
let defaultExporter = THREE.GLTFExporter
|
||||||
|
xrf.loaders['gltf'].exporter = defaultExporter
|
||||||
|
xrf.loaders['glb'].exporter = defaultExporter
|
||||||
|
|
||||||
|
function download(dataurl, filename) {
|
||||||
var a = document.createElement("a");
|
var a = document.createElement("a");
|
||||||
a.href = dataurl;
|
a.href = dataurl;
|
||||||
a.setAttribute("download", filename);
|
a.setAttribute("download", filename);
|
||||||
a.click();
|
a.click();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let file = document.location.search.replace(/\?/,'')
|
|
||||||
fetchAndDownload( file, file )
|
function exportScene(scene,ext){
|
||||||
|
const exporter = new (xrf.loaders[ext].exporter || defaultExporter)
|
||||||
|
document.dispatchEvent( new CustomEvent('download',{detail:{scene,ext}}) )
|
||||||
|
exporter.parse(
|
||||||
|
scene,
|
||||||
|
function ( glb ) { download(glb, `${file}.${ext}`) }, // ready
|
||||||
|
function ( error ) { console.error(error) }, // error
|
||||||
|
{binary:true}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load original scene and overwrite with updates
|
||||||
|
let url = document.location.search.replace(/\?/,'')
|
||||||
|
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
||||||
|
const Loader = xrf.loaders[ext]
|
||||||
|
loader = new Loader().setPath( dir )
|
||||||
|
loader.load(url, (model) => {
|
||||||
|
exportScene(model.scene,ext,file)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
updateHashPosition(randomize){
|
updateHashPosition(randomize){
|
||||||
|
|
@ -269,9 +292,11 @@ window.frontend = (opts) => new Proxy({
|
||||||
|
|
||||||
let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}`
|
let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}`
|
||||||
let newHash = document.location.hash.replace(/[&]?(pos|rot)=[0-9\.-]+,[0-9\.-]+,[0-9\.-]+/,'')
|
let newHash = document.location.hash.replace(/[&]?(pos|rot)=[0-9\.-]+,[0-9\.-]+,[0-9\.-]+/,'')
|
||||||
newHash += `&${lastPos}`
|
if( lastPos != "pos=" ){
|
||||||
document.location.hash = newHash.replace(/&&/,'&')
|
newHash += `&${lastPos}`
|
||||||
.replace(/#&/,'')
|
document.location.hash = newHash.replace(/&&/,'&')
|
||||||
|
.replace(/#&/,'')
|
||||||
|
}
|
||||||
this.copyToClipboard( window.location.href );
|
this.copyToClipboard( window.location.href );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,8 @@ window.SnackBar = function(userOptions) {
|
||||||
_Container.removeChild(_Element);
|
_Container.removeChild(_Element);
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
if( _Options.onclose ) _Options.onclose()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_Options = { ..._OptionDefaults, ...userOptions }
|
_Options = { ..._OptionDefaults, ...userOptions }
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ class XRF {
|
||||||
guessType(this, value); // 1. extract the type
|
guessType(this, value); // 1. extract the type
|
||||||
// validate
|
// validate
|
||||||
var ok:Bool = true;
|
var ok:Bool = true;
|
||||||
|
if( value.length == 0 ) ok = false;
|
||||||
if( !is(T_FLOAT) && is(T_VECTOR2) && !(Std.isOfType(x,Float) && Std.isOfType(y,Float)) ) ok = false;
|
if( !is(T_FLOAT) && is(T_VECTOR2) && !(Std.isOfType(x,Float) && Std.isOfType(y,Float)) ) ok = false;
|
||||||
if( !(is(T_VECTOR2) || is(T_STRING)) && is(T_VECTOR3) && !(Std.isOfType(x,Float) && Std.isOfType(y,Float) && Std.isOfType(z,Float)) ) ok = false;
|
if( !(is(T_VECTOR2) || is(T_STRING)) && is(T_VECTOR3) && !(Std.isOfType(x,Float) && Std.isOfType(y,Float) && Std.isOfType(z,Float)) ) ok = false;
|
||||||
return ok;
|
return ok;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue