I am coding a three.js simulation/animation and am having a hard time understanding why hardcoding an array index to a custom class instantiation ("physicsObjects[4]") works, but using the i variable in a for loop ("physicsObjects[i]") does not.
When successful, the updateTail() adjusts the a three.js line position attribute, and then I must set needsUpdate = true as shown in the Three.js documentation to redraw.
In the first example, it works successfully (although only for ONE of the objects, 4).
physicsObjects[i] has a .tail property which is a THREE.LineSegments(geometry,material)
for (let i = 0; i < physicsObjects.length; i++) {
physicsObjects[4].updateTail()
physicsObjects[4].tail.geometry.attributes.position.needsUpdate = true
}
It also works for 2 of my physics objects if I do this.
for (let i = 0; i < physicsObjects.length; i++) {
physicsObjects[4].updateTail()
physicsObjects[4].tail.geometry.attributes.position.needsUpdate = true
physicsObjects[7].updateTail()
physicsObjects[7].tail.geometry.attributes.position.needsUpdate = true
}
But if I want to iterate, it does NOT work. The only difference is that I am indexing with 'i' instead of a hardcoded index?
for (let i = 0; i < physicsObjects.length; i++) {
physicsObjects[i].updateTail()
physicsObjects[i].tail.geometry.attributes.position.needsUpdate = true
}
This is the error I get.
Uncaught TypeError: Cannot read properties of undefined (reading 'geometry')
at animate (app.js:159:32)
Here's my entire animate() draw loop for reference:
function animate() {
//Frame Start up
requestAnimationFrame(animate);
//Force Application
if (frameIndex % 1 == 0) {
for (let i = 0; i < physicsObjects.length; i++) {
for (let j = 0; j < physicsObjects.length; j++) {
if (i !== j) {
let f = physicsObjects[i].attract(physicsObjects[j])
physicsObjects[i].applyForce(f)
physicsObjects[i].updatePhysics()
physicsObjects[i].updateGeometry()
}
}
}
}
//Testing adding a tail to the objects
for (let i = 0; i < physicsObjects.length; i++) {
physicsObjects[4].updateTail()
physicsObjects[4].tail.geometry.attributes.position.needsUpdate = true
}
const time = performance.now();
controls.update(time, prevTime)
renderer.render(scene, camera);
stats.update()
//Frame Shut Down
prevTime = time;
}
Why can't I iterate with a loop?