Open slechanii opened 2 years ago
@slechanii have you considered using Sprites? The very definition of a Sprite is a (planar) object that always faces the camera POV, which sounds like what you're seeking.
@slechanii have you considered using Sprites? The very definition of a Sprite is a (planar) object that always faces the camera POV, which sounds like what you're seeking.
Thanks for answering quickly!
I was indeed using sprites before and it did the job well, the problem is that from I what I saw, using sprites makes it impossible to use hover / onclick events due to a bug with aframe (gathered from past issues and having problems making it work, might have been fixed ?)
If it hasn't been fixed it means that I can't use sprites as I need hover & onclick on nodes for what i'm trying to achieve.
If sprites are not usable do you have an idea on how I could make the nodes always look at the camera ?
Currently I'm facing 2 issues :
Thanks for your help!
@slechanii the reason behind the Sprite issue in Aframe is mentioned here: https://github.com/vasturiano/3d-force-graph-vr/issues/31#issuecomment-1043570188
That issue eventually originates in the Aframe module, so there's not a whole lot that can be done to work around it.
Similarly, I'm also not sure how easy it would be to implement Sprite-like behaviour without using actual Sprite objects.
I also encountered this problem and wrote a component to deal with it. Essentially what this does is to wrap each node in an A-Frame <a-sphere>
, which makes dealing with them much more tractable. The code below also attaches a <a-text>
entity to each sphere, and makes them always look towards the camera.
/* helper for vasturiano/3d-force-graph-vr
* draw a sphere around each force graph node, to make it easy to point to them with the ray caster,
* and attach a text label (which rotates to always face the camera)
* after the graph has been created, use something like
* fgEl.setAttribute('spherize', {})
* to create the spheres
*/
AFRAME.registerComponent('spherize', {
schema: {},
dependencies: ['forcegraph'],
init: function () {
// spheres are cached here and re-used
this.spheres = new Map()
},
tick: function (time, timeDelta) {
document
.querySelector('[forcegraph]')
.components.forcegraph.forceGraph.children.forEach((child) => {
if (child.type == 'Mesh' && child.__data.id) {
let sphereEl = this.spheres.get(child.__data.id)
if (sphereEl) {
// reuse existing sphere and label, but change its position
sphereEl.object3D.position.copy(child.position)
} else {
sphereEl = document.createElement('a-sphere')
sphereEl.classList.add('node')
sphereEl.id = child.__data.id
this.spheres.set(child.__data.id, sphereEl)
sphereEl.setAttribute('position', child.position)
let radius = child.geometry.parameters.radius + 0.1
sphereEl.setAttribute('radius', radius)
let color = child.__data.color || 'white'
let compColor = lightOrDark(standardize_color(color)) == 'light' ? 'black' : 'white'
sphereEl.setAttribute('color', color)
this.el.appendChild(sphereEl)
let label = document.createElement('a-entity')
label.setAttribute('text', {
value: splitText(child.__data.label, 9),
color: compColor,
width: 5 * radius,
align: 'center',
})
sphereEl.setAttribute('look-at', '#cameraRig')
label.setAttribute('position', {x: 0, y: 0, z: radius})
sphereEl.appendChild(label)
}
}
})
},
})
(the line let compColor = lightOrDark(standardize_color(color)) == 'light' ? 'black' : 'white'
sets compColor
to white or black depending on which gives a better contrast with the colour of the sphere)
Hi, i'm trying to make all my nodes (3D meshes) look at the camera position at all times, I am getting the camera position and making the mesh look at its position whenever its rendered the problem is that it only gets executed when nodeThreeObject is called, is there a way for me to make the nodes look at the camera at all times despite not getting rerendered ?
EDIT : After running some tests I found out that while I'm getting a camera, the vector is always (0,0,0) (even atfer moving the camera and triggering a rerender), here is the code I'm using to get the camera and print the position vector inside the nodeThreeObject :
Thanks.