stencil test

This commit is contained in:
Leon van Kammen 2023-11-06 14:42:51 +01:00
parent fa42f0585c
commit 8b4fde3571
5 changed files with 229 additions and 79 deletions

File diff suppressed because one or more lines are too long

View file

@ -53,6 +53,7 @@ xrf.parseModel = function(model,url){
model.file = file
// eval embedded XR fragments
model.scene.traverse( (mesh) => {
mesh.renderOrder = 2 // render after stencil buffers
xrf.hashbus.pub.mesh(mesh,model)
})
model.animations.map( (a) => console.log("anim: "+a.name) )

View file

@ -29,17 +29,18 @@
*/
xrf.frag.href = function(v, opts){
opts.embedded = v // indicate embedded XR fragment
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
if( mesh.userData.XRF.href.exec ) return // mesh already initialized
if( mesh.material ) mesh.material = mesh.material.clone() // we need this so we can individually highlight meshes
// derived properties
const isLocal = v.string[0] == '#'
const isPlane = mesh.geometry && mesh.geometry.attributes.uv && mesh.geometry.attributes.uv.count == 4
const hasSrc = mesh.userData.src != undefined
let click = mesh.userData.XRF.href.exec = (e) => {
let isLocal = v.string[0] == '#'
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)}`
xrf
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
@ -76,9 +77,12 @@ xrf.frag.href = function(v, opts){
mesh.addEventListener('mousemove', selected(true) )
mesh.addEventListener('mouseleave', selected(false) )
if( isLocal && isPlane && !hasSrc ) xrf.portalNonEuclidian(v,opts)
// lazy add mesh (because we're inside a recursive traverse)
setTimeout( (mesh) => {
xrf.interactive.add(mesh)
if( mesh.material ) mesh.material = mesh.material.clone() // clone, so we can individually highlight meshes
xrf.emit('interactionReady', {mesh,xrf:v,clickHandler: mesh.userData.XRF.href.exec })
}, 0, mesh )
}

View file

@ -0,0 +1,41 @@
xrf.portalNonEuclidian = function(v, opts){
let { frag, mesh, model, camera, scene, renderer, THREE} = opts
let toFrag = xrf.URI.parse( v.string )
// turn plane into stencilplane
mesh.material = new THREE.MeshPhongMaterial({ color: 'green' });
mesh.material.depthWrite = false;
mesh.material.stencilWrite = true;
mesh.material.stencilRef = xrf.portalNonEuclidian.stencilRef;
mesh.material.stencilFunc = THREE.AlwaysStencilFunc;
mesh.material.stencilZPass = THREE.ReplaceStencilOp;
mesh.cam = xrf.camera.getCam().clone()
mesh.cam.position.x = toFrag.pos.x
mesh.cam.position.y = toFrag.pos.y + 1
mesh.cam.position.z = toFrag.pos.z
mesh.isStencil = true
mesh.onBeforeRender = function( renderer, scene, camera, geometry, material, group ){
xrf.scene.traverse( (n) => !n.isStencil && n.material ? n.material.stencilRef = this.material.stencilRef : false )
xrf.renderer.render( xrf.scene, this.cam )
}
mesh.onAfterRender = function( renderer, scene, camera, geometry, material, group ){
xrf.scene.traverse( (n) => !n.isStencil && n.material ? n.material.stencilRef = 0 : false )
}
xrf.portalNonEuclidian.stencilRef += 1 // each portal has unique stencil id
// OBJECT INSIDE CUBE
//objectMat.stencilWrite = true;
//objectMat.stencilRef = stencilRef;
//objectMat.stencilFunc = THREE.EqualStencilFunc;
//const object = new THREE.Mesh(objectGeom, objectMat);
//scene.add(object);
console.log("enabling stencil plane")
}
xrf.portalNonEuclidian.stencilRef = 1

View file

@ -13,9 +13,17 @@ let loadVideo = (mimetype) => function(url,opts){
let mat = new xrf.THREE.MeshBasicMaterial()
mat.map = texture
mesh.material = mat
// set range
video.addEventListener('timeupdate', function timeupdate() {
if (video.t && video.currentTime < video.t.y || video.currentTime >= video.y.z ) {
vid.currentTime = video.t.y
}
},false)
})
video.src = url
video.playXRF = (t) => {
video.t = t
if( t.x == 0 ) video.pause()
else{
video.playbackRate = Math.abs( t.x ) // html5 video does not support reverseplay :/