Toggle navigation
Toggle navigation
This project
Loading...
Sign in
arcs
/
arcs.js-components
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jean-Yves Didier
2022-05-21 19:26:59 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
6be5e1117df4c6510dee2053894476ded5ba5668
6be5e111
1 parent
2368fe7e
merge
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
134 additions
and
121 deletions
components/filter.js
components/logger.js
components/uimapper.js
components/xrviewer.js
package.json
components/filter.js
View file @
6be5e11
import
ARCS
from
'../
build
/arcs.js'
;
import
ARCS
from
'../
engine
/arcs.js'
;
let
Filter
;
...
...
@@ -30,13 +30,12 @@ Filter = ARCS.Component.create(
function
(
config
)
{
let
self
=
this
;
let
_config
=
config
||
{};
self
.
signals
=
self
.
signals
||
{};
let
_config
=
config
??
{};
//self.signal(self.signals);
if
(
_config
.
signals
)
{
_config
.
signals
.
forEach
(
e
=>
{
self
.
signal
s
[
e
]
=
[]
;
self
.
signal
(
e
)
;
});
}
...
...
@@ -44,9 +43,10 @@ Filter = ARCS.Component.create(
_config
.
slots
.
forEach
(
e
=>
{
if
(
!
e
.
slot
||
!
e
.
func
)
return
;
let
slotName
=
e
.
slot
;
let
slotFunc
=
new
Function
(
'self'
,
`return
${
e
.
func
}
`
)(
self
);
self
.
slots
.
push
(
slotName
);
self
[
slotName
]
=
slotFunc
;
let
slotFunc
=
Array
.
isArray
(
e
.
func
)?
new
Function
(
'self'
,
`return
${
e
.
func
.
join
(
' '
)}
`
)(
self
):
new
Function
(
'self'
,
`return
${
e
.
func
}
`
)(
self
);
self
.
slot
(
slotName
,
slotFunc
);
});
}
},
...
...
components/logger.js
View file @
6be5e11
import
ARCS
from
'../build/arcs.js'
;
var
Logger
;
let
Logger
;
var
indexedDB
=
window
.
indexedDB
;
const
indexedDB
=
window
.
indexedDB
;
// two modes: websockets or indexeddb
// the idea is to add a timestamp as well as a timestamp for the start of
...
...
@@ -50,7 +50,18 @@ var toStructuredData = function( obj) {
return
obj
;
};
/**
* @class Logger
* @classdesc Logging system for ARCS.js
* @param [config] {object} configuration object for the logger
* @param [config.dbconfig] {object} use of indexedDB browser facility to record data
* @param [config.dbconfig.name="ARCS"] {string} database name
* @param [config.dbconfig.table="logtable"] {string} table name
* @param [config.dbconfig.clear] {boolean} if set to true, resets the table
* @param [config.server] {string} URL for websocket receiver. Can be used instead of database
* @param [config.slots] {Array.string} List of slots that need to be created.
* Each slot is then considered as an event to record when called.
*/
Logger
=
ARCS
.
Component
.
create
(
function
(
obj
)
{
var
i
;
...
...
components/uimapper.js
View file @
6be5e11
import
ARCS
from
'../
build
/arcs.js'
;
import
ARCS
from
'../
engine
/arcs.js'
;
let
UIMapper
;
...
...
@@ -6,17 +6,12 @@ let UIMapper ;
* UIMapperSlot
* An item describing a slot for an UIMapper component
* @typedef {Object} UIMapperSlot
* @property param {string} a string representing a parameter. It can reach
* subcomponents of an object by using the notation X.subcomp1.subcomp2 ...
* where X value is the position index of the parameter
* @property field {string} a string representing a reference to an HTML element
* and its subcomponents in the same way as the param property. However, the X
* component relates to a CSS selector (without CSS classes)
* @property format {string} a string representing code for a callback function.
* The callback should only expect one parameter, which is the value given by
* the parameter param
* @property value a value that should be injected by the slot to the HTML field.
* It can be used instead of param.
* @property index {number} the index of the slot parameter to use for the
* callback function
* @property selector {string} a CSS selector to target a DOM element
* @property func {string} a string representing code for a callback function.
* The callback function should expect two parameters, which are the
* DOM element and the parameter value
*/
/**
...
...
@@ -45,54 +40,32 @@ UIMapper = ARCS.Component.create(
let
self
=
this
;
// returns a map function
const
mapFunction
=
function
(
param
,
field
,
format
,
val
)
{
let
params
=
param
.
split
(
'.'
);
let
func
=
null
;
if
(
format
!==
undefined
)
{
func
=
new
Function
(
'self'
,
`return
${
format
}
`
)(
self
);
}
let
fields
=
field
.
split
(
'.'
);
let
eltField
=
document
.
querySelector
(
fields
[
0
]);
for
(
let
i
=
1
;
i
<
fields
.
length
-
1
;
i
++
)
{
eltField
=
eltField
[
fields
[
i
]];
}
return
function
()
{
let
value
;
if
(
val
===
undefined
)
{
value
=
arguments
[
params
[
0
]];
for
(
let
i
=
1
;
i
<
params
.
length
;
i
++
)
{
value
=
value
[
params
[
i
]];
}
}
else
{
value
=
val
;
}
eltField
[
fields
[
fields
.
length
-
1
]]
=
(
func
)?((
typeof
func
===
'function'
)?
func
(
value
):
func
):
value
;
}
const
mapFunction
=
function
(
index
,
selector
,
func
)
{
let
elt
=
document
.
querySelector
(
selector
);
let
actualFunc
=
Array
.
isArray
(
func
)?
new
Function
(
'self'
,
`return
${
func
.
join
(
' '
)}
`
)(
self
):
new
Function
(
'self'
,
`return
${
func
}
`
)(
self
);
return
function
()
{
actualFunc
(
elt
,
arguments
[
index
]);
};
};
obj
=
obj
||
{};
obj
=
obj
??
{};
if
(
obj
.
slots
)
{
for
(
let
p
in
obj
.
slots
)
{
let
slotName
=
p
;
let
slotFunction
=
function
(
pobj
)
{
let
functions
=
pobj
.
map
(
elt
=>
{
return
mapFunction
(
elt
.
index
,
elt
.
selector
,
elt
.
func
)
});
return
function
()
{
pobj
.
map
(
elt
=>
{
mapFunction
(
elt
.
param
,
elt
.
field
,
elt
.
format
,
elt
.
value
).
apply
(
null
,
arguments
);
});
functions
.
forEach
(
f
=>
{
f
.
apply
(
null
,
arguments
)
});
};
}
if
(
self
.
slots
.
indexOf
(
slotName
)
<
0
)
{
self
.
slots
.
push
(
slotName
);
self
[
slotName
]
=
slotFunction
(
obj
.
slots
[
p
]);
}
self
.
slot
(
slotName
,
slotFunction
(
obj
.
slots
[
p
]));
};
}
self
.
signals
=
self
.
signals
||
{};
/*** SIGNALS PART **/
self
.
signals
=
self
.
signals
??
{};
let
osignals
=
obj
.
signals
;
...
...
@@ -115,11 +88,12 @@ UIMapper = ARCS.Component.create(
}
if
(
domElt
)
{
domElt
.
addEventListener
(
signalDescr
.
event
,
self
=>
{
domElt
.
addEventListener
(
'beforexrselect'
,
e
=>
{
e
.
preventDefault
();
});
domElt
.
addEventListener
(
signalDescr
.
event
,
(()
=>
{
return
e
=>
self
.
emit
(
s
,
e
)
});
})
())
;
}
self
.
signal
s
[
s
]
=
[]
;
self
.
signal
(
s
)
;
}
}
...
...
components/xrviewer.js
View file @
6be5e11
import
ARCS
from
'../
build
/arcs.js'
;
import
ARCS
from
'../
engine
/arcs.js'
;
import
*
as
THREE
from
'../deps/three.js/index.js'
;
import
{
ARButton
}
from
'../deps/three.js/ARButton.js'
;
...
...
@@ -16,11 +16,14 @@ var XRViewer;
XRViewer
=
ARCS
.
Component
.
create
(
/** @lends XRViewer.prototype */
function
(
config
)
{
let
renderer
,
scene
,
camera
;
let
renderer
,
root
,
scene
,
camera
;
let
sceneId
;
let
container
;
let
self
=
this
;
let
defaultStyle
;
let
controller
;
let
button
;
let
binding
;
let
_config
=
config
||
{};
...
...
@@ -39,16 +42,19 @@ XRViewer = ARCS.Component.create(
let
firstFrame
=
true
;
// scenegraph initializations
scene
=
new
THREE
.
Scene
();
root
=
new
THREE
.
Scene
();
scene
=
new
THREE
.
Group
();
root
.
add
(
scene
);
renderer
=
new
THREE
.
WebGLRenderer
();
renderer
=
new
THREE
.
WebGLRenderer
(
{
alpha
:
true
}
);
//renderer.setClearColor(0x000000, 1);
renderer
.
setSize
(
container
.
width
,
container
.
height
);
renderer
.
setPixelRatio
(
window
.
devicePixelRatio
);
renderer
.
xr
.
enabled
=
true
;
renderer
.
xr
.
cameraAutoUpdate
=
false
;
//
renderer.xr.cameraAutoUpdate = false;
container
.
appendChild
(
renderer
.
domElement
);
rootOverlay
.
appendChild
(
ARButton
.
createButton
(
renderer
,
_config
.
sessionConfig
));
button
=
ARButton
.
createButton
(
renderer
,
_config
.
sessionConfig
);
rootOverlay
.
appendChild
(
button
);
var
theta
=
45
;
camera
=
new
THREE
.
PerspectiveCamera
(
theta
,
container
.
width
/
container
.
height
,
0.01
,
10
);
...
...
@@ -57,6 +63,17 @@ XRViewer = ARCS.Component.create(
_light
.
position
.
set
(
0
,
5
,
5
);
scene
.
add
(
_light
);
scene
.
add
(
camera
);
let
origin
=
new
THREE
.
Mesh
(
new
THREE
.
SphereGeometry
(
0.02
,
32
,
32
),
new
THREE
.
MeshBasicMaterial
({
color
:
'red'
,
wireframe
:
true
,
side
:
THREE
.
DoubleSide
}));
root
.
add
(
origin
);
let
sOrigin
=
new
THREE
.
Mesh
(
new
THREE
.
SphereGeometry
(
0.02
,
32
,
32
),
new
THREE
.
MeshBasicMaterial
({
color
:
'green'
,
wireframe
:
true
,
side
:
THREE
.
DoubleSide
}));
scene
.
add
(
sOrigin
);
controller
=
renderer
.
xr
.
getController
(
0
);
controller
.
addEventListener
(
'select'
,
()
=>
{
console
.
log
(
'xr select'
);
this
.
emit
(
'onSelect'
,
controller
);
});
/*renderer.domElement.addEventListener('webglcontextlost', (event) => {
console.log(event);
...
...
@@ -69,9 +86,16 @@ XRViewer = ARCS.Component.create(
* @slot
* @function XRViewer#addScene
*/
this
.
addScene
=
function
(
subScene
)
{
this
.
add
XR
Scene
=
function
(
subScene
)
{
scene
.
add
(
subScene
);
};
this
.
addXRCameraScene
=
function
(
subScene
)
{
camera
.
add
(
subScene
);
};
this
.
addScene
=
function
(
subScene
)
{
root
.
add
(
subScene
);
};
/**
* Removes an object from the current 3D scene
...
...
@@ -79,94 +103,98 @@ XRViewer = ARCS.Component.create(
* @slot
* @function XRViewer#removeScene
*/
this
.
removeScene
=
function
(
subScene
)
{
this
.
remove
XR
Scene
=
function
(
subScene
)
{
scene
.
remove
(
subScene
);
};
/**
* Sets the pose
* @param pos {object} a position with x, y and z coordinates
* @param rot {object} unused so far
* @slot
* @function XRViewer#setPose
*/
this
.
setPose
=
function
(
pos
,
rot
)
{
let
session
=
renderer
.
xr
.
getSession
();
let
p
=
camera
.
position
;
let
q
=
new
THREE
.
Quaternion
();
q
.
setFromRotationMatrix
(
camera
.
matrixWorld
);
session
.
requestReferenceSpace
(
renderer
.
xr
.
getReferenceSpace
()).
then
(
(
space
)
=>
{
let
xrSpace
=
space
;
xrSpace
=
xrSpace
.
getOffsetReferenceSpace
(
new
XRRigidTransform
(
{
x
:
p
.
x
,
y
:
p
.
y
,
z
:
p
.
z
,
w
:
1
},
{
x
:
q
.
x
,
y
:
q
.
y
,
z
:
q
.
z
,
w
:
q
.
w
}
)
);
// we will also have to modify the orientation
// because offset position is not enough
xrSpace
=
xrSpace
.
getOffsetReferenceSpace
(
new
XRRigidTransform
(
{
x
:
pos
.
x
,
y
:
pos
.
y
,
z
:
pos
.
z
,
w
:
1
},
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
1
}
)
);
}
);
this
.
removeScene
=
function
(
subScene
)
{
root
.
remove
(
subScene
);
};
this
.
setMatrixRotation
=
function
(
mat
)
{
let
m
=
new
THREE
.
Matrix4
();
m
.
copy
(
mat
);
m
.
invert
();
scene
.
position
.
setFromMatrixRotation
(
m
);
};
this
.
setMatrixPosition
=
function
(
mat
)
{
let
m
=
new
THREE
.
Matrix4
();
m
.
copy
(
mat
);
m
.
invert
();
scene
.
position
.
setFromMatrixPosition
(
m
);
};
this
.
setMatrixPose
=
function
(
mat
)
{
scene
.
rotation
.
setFromRotationMatrix
(
mat
);
scene
.
position
.
setFromMatrixPosition
(
mat
);
};
/**
* Starts the animation loop.
* Each time an animation frame is obtained, preRender and postRender
* signals are triggered
* @slot
* @function XRViewer#start
* @triggers preRender
* @triggers postRender
* @emits onRender
* @emits onStarted
* @emits onEnded
*/
this
.
start
=
function
()
{
renderer
.
setAnimationLoop
(
render
);
};
/* not a good idea, webxr MUST BE manually activated ! */
/*this.activate = function() {
button.click();
this.start();
};*/
let
render
=
function
(
time
,
frame
)
{
if
(
frame
)
{
renderer
.
xr
.
updateCamera
(
camera
);
if
(
firstFrame
)
{
binding
=
new
XRWebGLBinding
(
frame
.
session
,
renderer
.
getContext
());
renderer
.
xr
.
getSession
().
addEventListener
(
'end'
,()
=>
{
firstFrame
=
true
;
rootOverlay
.
style
.
display
=
defaultDisplay
;
self
.
setMatrixPose
(
new
THREE
.
Matrix4
());
self
.
emit
(
'onEnded'
);
});
firstFrame
=
false
;
self
.
emit
(
'onStarted'
);
}
//console.log(JSON.stringify(renderer.xr.getCamera().position));
let
pose
=
frame
.
getViewerPose
(
renderer
.
xr
.
getReferenceSpace
());
//console.log(pose);
/*for (let xrView of pose.views) {
if (xrView.camera) {
console.log("I can see a camera");
} */
/*if (pose) {
console.log(pose.views[0].projectionMatrix);
}*/
// if this works, then we simplify the thing
frame
.
manager
=
renderer
.
xr
;
frame
.
renderer
=
renderer
;
frame
.
binding
=
binding
;
self
.
emit
(
"onRender"
,
time
,
renderer
.
xr
.
getCamera
(),
frame
);
}
renderer
.
render
(
scene
,
camera
);
renderer
.
render
(
root
,
camera
);
}
},
/** @lends XRViewer.slots */
[
'addScene'
,
'removeScene'
,
'start'
,
'setPose'
],
[
'onRender'
,
'onEnded'
,
'onStarted'
]
[
'addScene'
,
'removeScene'
,
'addXRScene'
,
'addXRCameraScene'
,
'removeXRScene'
,
'start'
,
'setPose'
,
'setMatrixPose'
,
'setMatrixPosition'
,
'setMatrixRotation'
],
[
'onRender'
,
'onEnded'
,
'onStarted'
,
'onSelect'
]
);
/**
* emitted when a webXR session is operational
* @function XRViewer#onStarted
* @signal
*/
/**
* emitted when a frame is obtained after rendering of the scene.
* @function XRViewer#onRender
...
...
package.json
View file @
6be5e11
...
...
@@ -25,11 +25,11 @@
"author"
:
"Jean-Yves Didier"
,
"license"
:
"GPL-3.0-or-later"
,
"dependencies"
:
{
"arcsjs"
:
"^0.9.
1
"
,
"arcsjs"
:
"^0.9.
2
"
,
"js-aruco"
:
">=0.1"
,
"jsqr"
:
"^1.4.0"
,
"three"
:
">=0.131"
,
"webpack"
:
"^5.51.1"
,
"jsqr"
:
"^1.4.0"
"webpack"
:
"^5.66.0"
},
"private"
:
true
,
"devDependencies"
:
{
...
...
Please
register
or
login
to post a comment