I am having troubles with accessing properties even though they exist in the object, but typescript tells me they do not. I create a particles object, which contains the geometry of the shape, and a material. I need to be able to access the geometry vertices of the particle, but typescript throws a fit when I try. For example, this.particles.geometry.vertices.length should return the length of my vertices, but typescript says vertices do not exist in geometry when it is actually there.
My problem occurs after the image is loaded, vertices are created, and then I need to move them to there destination index, but it says the this.particles.geometry.vertices does not exist.
Here is my particle object which contains the geometry, and inside the geometry is a property that is vertices that does contain all my vertices, but I cannot access them the way I am showing.

Here is my full source code. The drawImage method will draw all the vertices correct, and push the vertex object into my geometry object. Then Once that is done I add the geometry to the particles and it works just fine, and I add it to the scene and get all my vertices displayed. Problem is I cannot access my vertices to manipulate them. So my particles object, drawImage and render method containing my for loop is where all this happens. In my render method it just says (TS) Property 'vertices' does not exists on type 'Geometry | buffer geometry'. It does exist and I show that with the image that my particles object which is a point object contains my geometry and that geometry has a property inside that has all my vertices called vertices.
import { Component, AfterViewInit, ElementRef, Input, ViewChild, HostListener} from '@angular/core';
import { TweenLite } from 'gsap';
import * as THREE from 'three';
declare const require: (moduleId: string) => any;
var OrbitControls = require('three-orbit-controls')(THREE);
@Component({
selector: 'shared-background-scene',
templateUrl: './backgroundScene.component.html',
styleUrls: ['./backgroundScene.component.scss']
})
export class BackgroundSceneComponent {
public scene: THREE.Scene;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private cameraTarget: THREE.Vector3;
public controls: THREE.OrbitControls;
public fieldOfView: number = 60;
public nearClippingPane: number = 1;
public farClippingPane: number = 1100;
@ViewChild('canvas')
private canvasRef: ElementRef;
public particles: THREE.Points;
public imageData: any;
public geometry = new THREE.Geometry();
public material = new THREE.PointsMaterial({
size: 3,
color: 0x313742,
sizeAttenuation: false
});
public loadImage() {
//load texture, which is the image, and then get the imagedata, and draw image.
var texture = new THREE.TextureLoader().load("assets/img/example-clouds.png", () => { console.log(texture); this.imageData = this.getImageData(texture.image); this.drawImage(); this.startRendering(); })
}
public getImageData(image: any) {
console.log(image);
// Create canvas for the image
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.width;
// Make sure context is 2d
let context = canvas.getContext("2d");
context!.drawImage(image, 0, 0);
//return the context to be saved to the imageData.
return context!.getImageData(0, 0, image.width, image.height);
}
public drawImage() {
// Create vertices to draw the image.
for (var y = 0, y2 = this.imageData.height; y < y2; y += 2) {
for (var x = 0, x2 = this.imageData.width; x < x2; x += 2) {
if (this.imageData.data[(x * 4 + y * 4 * this.imageData.width) + 3] > 128) {
let vertex:any = new THREE.Vector3();
vertex.x = Math.random() * 1000 - 500;
vertex.y = Math.random() * 1000 - 500;
vertex.z = -Math.random() * 500;
vertex.destination = {
x: x - this.imageData.width / 2,
y: -y + this.imageData.height / 2,
z: 0
};
vertex.speed = Math.random() / 200 + 0.015;
this.geometry.vertices.push(vertex);
}
}
}
console.log(this.geometry);
this.particles = new THREE.Points(this.geometry, this.material);
this.scene.add(this.particles);
console.log(this.particles);
requestAnimationFrame(this.render);
}
constructor() {
this.render = this.render.bind(this);
}
private get canvas(): HTMLCanvasElement {
return this.canvasRef.nativeElement;
}
private createScene() {
this.scene = new THREE.Scene();
}
private createCamera() {
let aspectRatio = this.getAspectRatio();
this.camera = new THREE.PerspectiveCamera(
this.fieldOfView,
aspectRatio,
this.nearClippingPane,
this.farClippingPane
);
// Set position and look at
this.camera.position.x = 10;
this.camera.position.y = 10;
this.camera.position.z = 100;
}
private getAspectRatio(): number {
let height = this.canvas.clientHeight;
if (height === 0) {
return 0;
}
return this.canvas.clientWidth / this.canvas.clientHeight;
}
private startRendering() {
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setClearColor(0xffffff, 1);
this.renderer.autoClear = true;
let component: BackgroundSceneComponent = this;
(function render() {
requestAnimationFrame(render);
component.render();
}());
}
public render() {
this.renderer.render(this.scene, this.camera);
for (var i = 0, j = this.particles.geometry.vertices; i < j; i++) {
var particle = this.particles.geometry.vertices[i];
particle.x += (particle.destination.x - particle.x) * particle.speed;
particle.y += (particle.destination.y - particle.y) * particle.speed;
particle.z += (particle.destination.z - particle.z) * particle.speed;
}
this.particles.geometry.verticesneedupdate = true;
}
public addControls() {
this.controls = new OrbitControls(this.camera);
this.controls.rotateSpeed = 1.0;
this.controls.zoomSpeed = 1.2;
this.controls.addEventListener('change', this.render);
}
private loadCubeModel() {
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
this.scene.add(cube);
}
/* Events */
private onResize(event: Event) {
this.canvas.style.width = "100%";
this.canvas.style.height = "100vh";
//console.log("onResize: " + this.canvas.clientWidth + ", " + this.canvas.clientHeight);
this.camera.aspect = this.getAspectRatio();
this.camera.updateProjectionMatrix();
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.render();
}
/* LIFECYCLE */
ngAfterViewInit() {
this.createScene();
this.createCamera();
this.loadImage(); // rendering starts here
this.loadCubeModel();
this.addControls();
}
}
Quick example of me using console.log(this.particles.geometry.vertices.length); and getting the correct output, but it still says it does not exist.
