Team Updates

Hackaton NASA 18
view raw 1 hosted with ❤ by GitHub
:host {
overflow: hidden;
width:100%;
height:100%;
display: flex;
}
.model {
width:100%;
height:100%;
}
<canvas#canvasclass="model" (click)="onClick($event)"></canvas>
import{
Component,
ElementRef,
EventEmitter,
HostListener,
OnInit,
Output,
ViewChild,
Input
}from'@angular/core';
import{Object3D,TextureLoader,Group,TGALoader,MeshPhongMaterial,CanvasTexture,Vector3}from'three';
import*asTHREEfrom'three';
import'./js/EnableThreeExamples';
import'three/examples/js/loaders/OBJLoader';
import'three/examples/js/loaders/MTLLoader';
import'three/examples/js/loaders/TDSLoader';
import'three/examples/js/loaders/TGALoader';
import'three/examples/js/controls/OrbitControls';
import'three/examples/js/controls/TrackballControls.js';
import{ThreeDModel}from'../models/3d.model';
@Component({
selector: 'app-scene',
templateUrl: './app-scene.component.html',
styleUrls: ['./app-scene.component.css']
})
exportclassAppSceneComponentimplementsOnInit{
_selectedModel: ThreeDModel;
@Input()
setselectedModel(value: ThreeDModel){
this._selectedModel=value;
this.changeModel();
}
getselectedModel(): ThreeDModel{
returnthis._selectedModel;
}
@Input()selectedLogo: ThreeDModel;
@Input()imageSize: number;
@Output()clickIntersect=newEventEmitter<Object3D>();
@ViewChild('canvas')privatecanvasRef: ElementRef;
privaterenderer: THREE.WebGLRenderer;
privatecamera: THREE.PerspectiveCamera;
publicadvertCanvas: HTMLCanvasElement;
publicscene: THREE.Scene;
publiccontrols: THREE.OrbitControls;
privatecurrentObject: Object3D;
privateobject: Object3D;
privateloader;
publiccolor: THREE.Color;
publictexture: THREE.CanvasTexture;
privatenormalLoader: TextureLoader;
privatetextureLoader: TGALoader;
publicfieldOfView=60;
publicnearClippingPane=1;
publicfarClippingPane=1100;
publiccanvasSize=4096;
privateanimationTimer;
backgroundScene: THREE.Scene;
backgroundCamera: THREE.Camera;
/* LIFECYCLE */
ngOnInit(){
window['a']=this;
this.createBackground();
this.createCamera();
this.createLight();
this.startRendering();
this.addControls();
}
createBackground(): any{
consttexture=THREE.ImageUtils.loadTexture('assets/background.jpg');
constbackgroundMesh=newTHREE.Mesh(
newTHREE.PlaneGeometry(4,4,0),
newTHREE.MeshBasicMaterial({
map: texture
}));
(backgroundMesh.materialasany).depthTest=false;
(backgroundMesh.materialasany).depthWrite=false;
// Create your background scene
this.backgroundScene=newTHREE.Scene();
this.backgroundCamera=newTHREE.Camera();
this.backgroundScene.add(this.backgroundCamera);
this.backgroundScene.add(backgroundMesh);
}
privategetcanvas(): HTMLCanvasElement{
returnthis.canvasRef.nativeElement;
}
privatechangeModel(){
if(!this.selectedModel){
return;
}
this.initNewScene();
letobj;
if(obj=this.scene.getObjectByName('currObj')){
obj.parent.remove(obj);
this.animationTimer=null;
this.render();
}
// if (this.selectedModel.name === 'Astronaut') {
// this.animationTimer = null;
// this.createSce();
// return;
// }
if(this.selectedModel.name==='Astronaut'){
this.animationTimer=null;
this.createAstronaut2();
return;
}
if(this.selectedModel.name==='Arian-1'){
this.animationTimer=null;
this.createRocket();
return;
}
this.createScene();
}
privatecreateRocket(){
lettexture;
constmanager=newTHREE.LoadingManager(()=>{});
this.textureLoader=newTHREE.TextureLoader(manager);
texture=this.textureLoader.load('assets/rocket1/rocket.jpg');
this.loader=new(THREEasany).MTLLoader();
this.loader.setPath(`assets/rocket1/`);
this.loader.load(`12217_rocket_v1_l1.mtl`,e=>{
e.preload();
new(THREEasany).OBJLoader()
.setPath('assets/rocket1/')
.load('12217_rocket_v1_l1.obj',(object)=>{
this.object=object;
window['r']=this.object;
this.object.position.set(0,-5.5,0);
this.object.scale.set(0.01,0.01,0.01);
this.object.receiveShadow=false;
this.animationTimer=this.startObjectAnimation(this.object);
// this.camera.lookAt(this.object.position);
this.object.traverse(child=>{
this.addCanvasTexture(child,this.object,texture);
});
this.object.name='currObj';
this.scene.add(this.object);
this.render();
},x=>{},err=>{});
});
}
privatecreateSce(){
this.loader=new(THREEasany).TDSLoader();
this.loader.setResourcePath(`assets/astronaut/textures/`);
this.loader.load(`assets/astronaut/astronaut.3ds`,e=>this.onAstroLoading(e));
this.textureLoader=newTHREE.TGALoader();
this.render();
}
privatecreateAstronaut2(){
new(THREEasany).OBJLoader()
.setPath('assets/astronaut2/')
.load('astronaut2.obj',(object)=>{
this.object=object;
window['e']=this.object;
this.object.traverse(child=>{
this.addCanvasTexture(child,this.object,texture);
});
this.object.position.set(0,-7,0);
this.object.receiveShadow=false;
this.object.scale.set(8,8,8);
this.animationTimer=this.startObjectAnimation(this.object);
this.object.name='currObj';
this.scene.add(this.object);
this.render();
},x=>{},err=>{});
lettexture;
constmanager=newTHREE.LoadingManager(()=>{});
this.textureLoader=newTHREE.TextureLoader(manager);
texture=this.textureLoader.load('assets/astronaut2/z2_Color_s.jpg');
// this.loader = new (THREE as any).MTLLoader();
// this.loader.setPath(`assets/astronaut2/`);
// this.loader.load(`astronaut2.mtl`, e => {
// e.preload();
// });
}
startObjectAnimation(object: Object3D){
returnsetInterval(()=>{
object.rotateY(0.1);
this.render();
},100);
}
privateonAstroLoading(collada: Group){
collada.children.forEach((e: THREE.Mesh)=>{
consttext=this.textureLoader.load('assets/astronaut/textures/astnt1_1.tga');
this.addCanvasTexture(e,this.object,text);
});
collada.name='currObj';
this.scene.add(collada);
}
privatecreateScene(){
this.loader=new(THREEasany).TDSLoader();
this.normalLoader=newTextureLoader();
constnormal=this.normalLoader.load(`assets/${this.selectedModel.path}/textures/${this.selectedModel.normal}`);
this.loader.setResourcePath(`assets/${this.selectedModel.path}/textures/`);
this.loader.load(`assets/${this.selectedModel.path}/${this.selectedModel.path}.3ds`,
e=>this.onModelLoadingCompleted(e,normal));
}
privateinitNewScene(){
this.scene=newTHREE.Scene();
// this.scene.add(new THREE.AxesHelper(200));
constlight=newTHREE.HemisphereLight();
this.scene.add(light);
if(this.camera){
this.scene.add(this.camera);
}
}
privateonModelLoadingCompleted(collada,normal){
this.currentObject=collada;
this.currentObject.traverse(object=>{
this.addCanvasTexture(object,this.currentObject,normal,true);
});
this.currentObject.receiveShadow=false;
this.currentObject.name='currObj';
this.scene.add(this.currentObject);
this.animationTimer=this.startObjectAnimation(this.currentObject);
this.render();
}
privatesetupCanvas(): void{
this.advertCanvas=document.createElement('canvas');
this.advertCanvas.width=this.canvasSize;
this.advertCanvas.height=this.canvasSize;
this.color=newTHREE.Color();
this.texture=newTHREE.CanvasTexture(this.advertCanvas);
}
privateaddCanvasTexture(object,currentObject,normal,isNormal=false): void{
this.setupCanvas();
constchild=objectasany;
if(!object.isMesh&&!child.material){
return;
}
isNormal ? child.material.normalMap=normal : child.material.map=normal;
child.material.lightMap=normal;
currentObject.add(newTHREE.Mesh(child.geometry,newMeshPhongMaterial({
map: this.texture,
alphaTest: 0.5
})));
}
privatecreateLight(){
// var directionalLight = new THREE.DirectionalLight( 0xffeedd );
// directionalLight.position.set( 0, 0, 2 );
// this.scene.add( directionalLight );
}
privatecreateCamera(){
constaspectRatio=this.getAspectRatio();
this.camera=newTHREE.PerspectiveCamera(
this.fieldOfView,
aspectRatio,
this.nearClippingPane,
this.farClippingPane
);
/**
* x: -13.51642127467603
y: 0.20744722870848967
z: -19.82593506593228
*/
// Set position and look at
this.camera.position.x=-10;
this.camera.position.y=0.75;
this.camera.position.z=-17;
this.camera.rotation.x=-2;
this.camera.rotation.y=0;
this.camera.rotation.z=-2;
}
privategetAspectRatio(): number{
constheight=this.canvas.clientHeight;
if(height===0){
return0;
}
returnthis.canvas.clientWidth/this.canvas.clientHeight;
}
privatestartRendering(){
this.renderer=newTHREE.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(0x1B1B1B,1);
this.renderer.autoClear=true;
this.render();
}
publicrender(){
if(this.renderer&&this.scene){
this.renderer.autoClear=false;
this.renderer.clear();
this.renderer.render(this.backgroundScene,this.backgroundCamera);
this.renderer.render(this.scene,this.camera);
}
}
publicaddControls(){
this.controls=newTHREE.OrbitControls(this.camera);
this.controls.rotateSpeed=1.0;
this.controls.zoomSpeed=1.2;
this.controls.addEventListener('change',()=>this.render());
}
/* EVENTS */
publiconClick(event: MouseEvent){
// Example of mesh selection/pick:
constraycaster=newTHREE.Raycaster();
constmouse=newTHREE.Vector2();
mouse.x=((event.clientX-300)/this.renderer.domElement.clientWidth)*2-1;
mouse.y=-(event.clientY/this.renderer.domElement.clientHeight)*2+1;
raycaster.setFromCamera(mouse,this.camera);
constobj: THREE.Object3D[]=[];
this.findAllObjects(obj,this.scene);
constintersects=raycaster.intersectObjects(obj);
// console.log('Scene has ' + obj.length + ' objects');
// console.log(intersects.length + ' intersected objects found');
if(intersects&&intersects.length){
intersects.forEach((intersect,index)=>{
if(index>1){
return;
}
// console.log(intersect);
constobject=intersect.object;
if(intersect.uv&&object&&(objectasany).material&&(objectasany).material.mapinstanceofCanvasTexture){
this.addCanvasObject({
offsetX: intersect.uv.x*this.canvasSize,
offsetY: (1-intersect.uv.y)*this.canvasSize
});
}
this.clickIntersect.emit(object);
});
}
}
publicaddCanvasObject(event: {offsetX: number,offsetY: number}): void{
if(!this.selectedLogo){
return;
}
constctx=this.advertCanvas.getContext('2d');
constimage=newImage(750,750);
image.src=this.selectedLogo.path;
ctx.drawImage(image,
event.offsetX-this.imageSize/2,
event.offsetY-this.imageSize/2,
this.imageSize,this.imageSize
);
this.texture.needsUpdate=true;
this.render();
}
privatefindAllObjects(pred: THREE.Object3D[],parent: THREE.Object3D){
// NOTE: Better to keep separate array of selected objects
if(parent.children.length>0){
parent.children.forEach((i)=>{
pred.push(i);
this.findAllObjects(pred,i);
});
}
}
@HostListener('window:resize',['$event'])
publiconResize(){
this.canvas.style.width='100%';
this.canvas.style.height='100%';
// 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();
}
publicsplitByMaterial(geometry,materials){
constparts=[];
constfaces=['a','b','c'];
letgeo,vMap,iMat;
geometry.faces.forEach(face=>{
if(face.materialIndex!==iMat){
if(iMat){
this.addPart(materials,iMat,parts,geo);
}
geo=newTHREE.Geometry();
vMap={};
iMat=face.materialIndex;
}
constf=face.clone();
faces.forEach(p=>{
constiv=face[p];
if(!vMap.hasOwnProperty(iv)){
vMap[iv]=geo.vertices.push(geometry.vertices[iv])-1;
}
f[p]=vMap[iv];
});
geo.faces.push(f);
});
this.addPart(materials,iMat,parts,geo);
returnparts;
}
privateaddPart(materials,iMat,parts,geo): void{
constmat=materials ? Object.assign({},materials[iMat]) : {};
mat.side=THREE.DoubleSide;
parts.push(newTHREE.Mesh(geo,mat));
}
}
THREE=require('three');
yauheni.dzirvukYauheni Dzirvuk
Team Stream Item
yauheni.dzirvukYauheni Dzirvuk
NASA Logo

SpaceApps is a NASA incubator innovation program.