I'm building a particle system in which particles have directions they are pointing at and I want to reflect that in an instance mesh I use to present them, but something is not quite working... It seems that the center of rotation and/or the up axis are not quite right, and despite me console logging stuff I could not find the problem. Here's the code:
const Particles = (particleSystem: TparticleSystem) => {
const mesh = useRef<THREE.InstancedMesh>(null);
const light = useRef<THREE.PointLight>(null);
const dummy = useMemo(() => new THREE.Object3D(), []);
const pyramid = useMemo(() => {
return {
vertices: [1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, -1, 0, 2, 0],
indices: [0, 1, 2, 2, 3, 0, 0, 4, 1, 1, 4, 2, 2, 4, 3, 3, 4, 0],
};
}, []);
useFrame(() => {
if (particleSystem !== undefined) {
particleSystem.update();
particleSystem.move();
particleSystem.particles.forEach((particle: Tparticle, index: number) => {
dummy.position.set(particle.pos.x, particle.pos.y, particle.pos.z);
dummy.lookAt(vec().copy(particle.pos).add(particle.dir)); // rotating weird
dummy.scale.set(1, 2, 1);
dummy.updateMatrix();
// And apply the matrix to the instanced item
if (mesh.current) mesh.current.setMatrixAt(index, dummy.matrix);
});
if (mesh.current) mesh.current.instanceMatrix.needsUpdate = true;
}
});
return (
<>
<pointLight ref={light} distance={40} intensity={3} color="lightblue" />
{particleSystem !== undefined && (
<instancedMesh ref={mesh} args={[, , particleSystem.num]}>
<polyhedronBufferGeometry
args={[pyramid.vertices, pyramid.indices, 1, 0]}
/>
<meshBasicMaterial
color="#2596be"
wireframe={Math.random() > 0.5 ? true : false}
/>
</instancedMesh>
)}
</>
);
};
I feel like maybe this is something to do with local and world coordinates, but I don't quite understand it.
Oh! and this vec stuff is just
const vec = function (x = 0, y = 0, z = 0) {
return new THREE.Vector3(x, y, z);
};
Related
i have this object and i have a problem...
Mesh coordinates are always 0 and i don't know how to fix it
I want to add multiple sprites to this one, but i can't with these coordinates (research from here)
THREE.DRACOLoader.setDecoderPath('Scripts/libs/draco/gltf/');
THREE.DRACOLoader.setDecoderConfig({ type: 'js' });
let loader = new THREE.GLTFLoader();
loader.setDRACOLoader(new THREE.DRACOLoader());
loader.load('/3D_Cars/Dacia_1410_Tuned/components/scene.gltf', function (gltf) {
carModel = gltf.scene.children[0];
gltf.scene.traverse(function (child) {
if (child.isMesh) {
console.log(child.name," ", child.matrixWorld.getPosition().x + ',' + child.matrixWorld.getPosition().y + ',' + child.matrixWorld.getPosition().z);
var v = new THREE.Vector3(0, 0, 0);
domEvents.addEventListener(carModel.getObjectByName(child.name), 'click', function (event) {
app.RenameAsCarParts(child.name)
console.log(child.name)
}, false)
//if (child.name == 'rim_RSL1_Aluminium_0') {
// child.position.set(100, 50, 3); //testing
// var spritey = makeTextSpriteNew(" Hello ",
// { fontsize: 15, textColor: { r: 0, g: 0, b: 0, a: 1.0 } });
// scene.add(spritey);
//}
}
});
carModel.getObjectByName('Body_paint_0').material = bodyMaterial;
carModel.rotation.set(Math.PI / 2, 0, 0);
carModel.rotateY(Math.PI);
scene.add(carModel);
});
Console screenshot:
Thanks!
Till now I have managed to achieve camera shifting from one place to another but it goes all of a sudden i want a animation or a smooth effect in between current and final camera point
function Rig({ children }) {
const outer = useRef(null)
const inner = useRef(null)
const [pos, setPos] = useState({
x: -12,
y: 20,
z: 34
})
const [type, setType] = useState('initial')
setTimeout(() => {
setType('third')
}, 5000)
useEffect(() => {}, [pos])
useFrame(({ camera, clock }) => {
if (type === 'initial') {
outer.current.position.y = THREE.MathUtils.lerp(outer.current.position.y, 0, 0.05)
inner.current.rotation.y = Math.sin(clock.getElapsedTime() / 8) * Math.PI
inner.current.position.z = 5 + -Math.sin(clock.getElapsedTime() / 2) * 10
inner.current.position.y = -5 + Math.sin(clock.getElapsedTime() / 2) * 2
}
if (type === 'final') {
camera.position.set(0, 20, 34)
}
})
return (
<group position={[0, -100, 0]} ref={outer}>
<group ref={inner}>{children}</group>
</group>
)
}
I read in the documentation this could be achieve through react spring or tween camera but i couldn't implement any of those
I use CameraControls npm i camera-controls, but don't know how to change transition speed
Example https://codesandbox.io/s/react-three-fiber-camera-controls-4jjor?file=/src/App.tsx
I'm trying to make a sphere that follows my cursor. Most of it is done, however, the sphere severely warps on the edges of my screen.
Middle of screen:
Edge of screen:
I have the default camera (fov changed) setup but I feel like it's the wrong one
Canvas:
const Canvas: NextPage<CanvasProps> = ({ children }) => {
const camera = { fov: 60, near: 0.1, far: 1000, position: [0, 0, 5] }
return (
<ThreeCanvas className="bg-gray-900" camera={camera}>
{children}
<Mouse />
</ThreeCanvas>
)
}
Mouse.tsx:
const Mouse: NextPage<MouseProps> = ({}) => {
const [active, setActive] = useState(false)
const { viewport } = useThree()
const { scale } = useSpring({ scale: active ? 0.7 : 1 })
useEffect(() => {
if (active) {
setTimeout(() => setActive(false), 200)
}
}, [active])
const ref = useRef()
useFrame(({ mouse }) => {
const x = (mouse.x * viewport.width) / 2
const y = (mouse.y * viewport.height) / 2
if (typeof ref !== undefined) {
// #ts-ignore
ref!.current.position.set(x, y, 0)
// #ts-ignore
ref!.current.rotation.set(-y, x, 0)
}
})
return (
<>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<animated.mesh scale={scale} onClick={() => setActive(!active)} ref={ref}>
<sphereGeometry args={[0.15, 32, 32]} />
<meshStandardMaterial color="beige" transparent />
</animated.mesh>
</>
)
}
I'm using Plotly.js to draw a 3-D scatter plot . On zoom , I want to check which points are visible . Can this be done on svg level ? or any plotly expert ?
Snippet:
var myPlot = document.getElementById("myDiv");
var trace = {
x: [1, 7, 2, 4,1],
y: [12, 9, 15, 12,2],
z: [1, 2, 4, 8,4],
// x: [1,2],
//y: [12,15],
//z: [1, 4],
mode: 'markers' ,
type: 'scatter3d' ,
marker: {size:5 }
}
var data = [trace];
var layout = {
margin: {
l: 0,
r: 0,
b: 0,
t: 0} ,
//title: {text: 'ReOptim8 Scatter Plot'},
scene: {
yaxis:{title: 'X-axis'},
xaxis:{title: 'y-axis'},
zaxis:{title: 'z-axis'},
camera: {eye: {x:1.25, y:1.25, z:1.25}}
}
};
var config = {
displayModebar : true,
displaylogo: false,
responsive: true
};
Plotly.plot( myPlot, data, layout, config );
Code pen link below :
https://codepen.io/aniwar/pen/wLOzZv
I have a data stream with e.g. the following values:
Observable.of(
[{time: 1000, a: 100},
{time: 1000, b: 100},
{time: 2000, a: 200}]
);
And need to merge the values based on time to get:
[{time: 1000, a: 100, b: 100},
{time: 2000, a: 200}]
I can use map and reduce but then I end up with a single map that I have to split somehow again. Is there a more straight forward way in RxJs?
You could just do an array reduce inside of a map operator. Might be a bit clearer than the groupBy and flatMap. This is more of a data mapping issue than an rxjs issue.
Rx.Observable.of(
[{time: 1000, a: 100},
{time: 1000, b: 100},
{time: 2000, a: 200}]
).map(data => {
return data.reduce((acc, cur) => {
const index = acc.findIndex(x => x.time === cur.time);
if (index >= 0) {
acc[index] = { ...acc[index], ...cur };
} else {
acc.push(cur);
}
return acc;
}, [])
})
.subscribe(x => { console.log('result', x); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.7/Rx.min.js"></script>
I got this in the end:
Observable.of(
[{time: 1000, channelKey: 'a', value: 100},
{time: 1000, channelKey: 'b',value: 100},
{time: 2000, channelKey: 'a', value: 200}]
)
.flatMap<any[], any>(x => x)
.groupBy(v => Math.floor(v.time.getTime() / 1000), v => {
return {[v.channelKey]: v.value}
})
.flatMap((group$) => group$.reduce((acc, cur) => Object.assign(cur, acc), {time: group$.key}))
.toArray()
.subscribe((v) => {
console.log("Value: ", v)
})