Three.js: Collada file not displaying the object properly with canvas

Created on 12 Mar 2018  路  17Comments  路  Source: mrdoob/three.js

When I use the same code for viewing the file without lights,animation and everything it works fine.Below I have attached the file that is working perfectly.

screenshot 153

But when I add lights and other files, it does not working correctly. I cannot able to identify what is the problem with the code.Below I have attached the file added with lights and other file types.

screenshot 157

But When I try to load same file with local software that is there any problem with the DAE file, it works perfectly. Below I will attach the screenshot how it should display

screenshot 162

Map.ts

    import { AfterViewInit, Component, ElementRef, ViewChild, HostListener } from '@angular/core';
    import { LoadingController } from 'ionic-angular';

    import * as THREE from 'three';
    import "./../../providers/three-enabler";
    import "three/examples/js/controls/OrbitControls";
    import "three/examples/js/loaders/ColladaLoader";

    @Component({
      selector: 'map',
      templateUrl: 'map.html'
    })

    export class MapComponent implements AfterViewInit{

      private renderer: THREE.WebGLRenderer;
      private camera: THREE.PerspectiveCamera;
      public scene: THREE.Scene;

      public fieldOfView: number = 20;
      public nearClippingPane: number = 1;
      public farClippingPane: number = 1100;

      public controls: THREE.OrbitControls;


      @ViewChild('canvas')
      private canvasRef: ElementRef;

      constructor(public loadingCtrl: LoadingController) {

        this.render = this.render.bind(this);
        this.onModelLoadingCompleted = this.onModelLoadingCompleted.bind(this);

      }


      private get canvas(): HTMLCanvasElement {
        return this.canvasRef.nativeElement;
      }

      private createScene() {
        this.scene = new THREE.Scene();
        var loader = new THREE.ColladaLoader();
        loader.load('assets/Buildings/MITblock.DAE', this.onModelLoadingCompleted);

      }

      private onModelLoadingCompleted(collada) {
         const loading = this.loadingCtrl.create({
          content:'Loading Please Wait...'
        });
        loading.present();

        var modelScene = collada.scene;
        this.scene.add(modelScene);

        loading.dismiss();
        this.render();
      }

      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 = 20;
        this.camera.position.z = 90;
      }

      private getAspectRatio(): number {
        let height = this.canvas.clientHeight;
        if (height === 0) {
          return 0;
        }
        this.canvas.style.width = "100%";
        this.canvas.style.height = "100%";
        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: MapComponent = this;

        (function render() {
          requestAnimationFrame(render);
          component.render();
        }());
      }

      public render() {

        this.renderer.render(this.scene, this.camera);

      }

      public addControls() {
        this.controls = new THREE.OrbitControls(this.camera);
        this.controls.rotateSpeed = 1.0;
        this.controls.zoomSpeed = 1.2;
        this.controls.addEventListener('change', this.render);

      }

      /* EVENTS */

      public onMouseDown(event: MouseEvent) {
        console.log("onMouseDown");
        event.preventDefault();

        // Example of mesh selection/pick:
        var raycaster = new THREE.Raycaster();
        var mouse = new THREE.Vector2();
        mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
        mouse.y = - (event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, this.camera);

        var obj: THREE.Object3D[] = [];
        this.findAllObjects(obj, this.scene);
        var intersects = raycaster.intersectObjects(obj);
        console.log("Scene has " + obj.length + " objects");
        console.log(intersects.length + " intersected objects found")
        intersects.forEach((i) => {
          console.log(i.object); // do what you want to do with object
        });

      }

      private findAllObjects(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);
          });
        }
      }

      public onMouseUp(event: MouseEvent) {
        console.log("onMouseUp");
      }


      @HostListener('window:resize', ['$event'])
      public onResize(event: Event) {


        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();

      }


      @HostListener('document:keypress', ['$event'])
      public onKeyPress(event: KeyboardEvent) {
        console.log("onKeyPress: " + event.key);
      }


      /* LIFECYCLE */
      ngAfterViewInit() {
        this.createScene();
        this.createCamera();
        this.startRendering();
        this.addControls();
      }


    }

Map.html

<canvas #canvas (mousedown)="onMouseDown($event)" (mouseup)="onMouseUp($event)"></canvas>
Help (please use the forum)

Most helpful comment

@Perinban BTW: This is how it feels implementing a loader for Collada and then test it with random dae files from the web 馃榿

Alt Text

All 17 comments

Could you put your code in a .ZIP (you can drag them into github comments) or create a live demo? You'll need to include the .dae file itself, most likely..

Friday.zip

@donmccurdy, I have attached both the Files in the Assets/Buildings Folder

Can reproduce the issue by opening the .dae files by themselves in https://threejs.org/editor/. I'm not sure if the files are properly formed, as I can't open them in Blender or COLLADA2GLTF here.

@donmccurdy Can I send the 3ds max scene file or any other formats? Ya, I too get the same problem in three js editor. But it works fine in open3mod software (http://www.open3mod.com/)

Probably worth trying FBX with the editor and THREE.FBXLoader I think.

@donmccurdy I never used the FBX loader, is there any sample I could use for Ionic 3 application?

I haven't used Ionic, but there is a general example using FBXLoader here: https://threejs.org/examples/?q=fbx#webgl_loader_fbx

Thanks @donmccurdy I will try that

I've analyzed the Collada files today. There are two problems.

  • IMO, the way transparency is defined does not conform to the standard. If there is just a <transparency> but no <transparent> tag, loaders have to assume default opaque mode A_ONE. Because the value of <transparency> is always zero in these files, some materials are transparent with opacity zero.
  • Besides, the files contain 16 light definitions which are interpreted as 16 point lights by ColladaLoader. This overexposes the scene.

If I remove the transparency and light definitions and use a simple light setup, output looks fine.

image

So from my point of view, the problems are caused by the .dae files or the respective exporter.

@Mugen87 I think, too many exports caused the problem Initially started with Revit then exported to fbx format and then imported to 3ds max. Then,I Used 3DS Max 2018 Collada Exporter. How to change the transparency and the point lights? and can u send the corrected dae file?

@Mugen87 Still Im getting the black scene
screenshot 167

If Im using three.js editor, similarly im getting like this
screenshot 168

But it works well with the external software
screenshot 169

Then wats the problem? Whats the problem with the code

You need to add a light source in your scene.

@Mugen87 How to add lights without overexposing the scene? Like you said you add simple light settings

You will probably want to put lights into the scene separately from the model. Or Add -> Point Light in the three.js editor menu. The issue is that 16 point lights is too many. See this example or the three.js forums for help with lighting.

Thanks @Mugen87 @donmccurdy, it works well

@Perinban BTW: This is how it feels implementing a loader for Collada and then test it with random dae files from the web 馃榿

Alt Text

Was this page helpful?
0 / 5 - 0 ratings