2013-02-22 105 views
8

我最近從官方網站使用我的collada對象(.dae)使用ColladaLoader.js獲得了three.js示例。 現在我的問題是,如何更改加載的collada對象顏色屬性並添加自定義紋理?我嘗試添加沒有運氣的紋理。更改Three.js collada對象的紋理和顏色

這裏是我的代碼(從原來的例子稍微改變):

function load_model(el) { 

      if (! Detector.webgl) Detector.addGetWebGLMessage(); 

      var container, stats; 

      var camera, scene, renderer, objects; 
      var particleLight, pointLight; 
      var dae, skin; 

      var loader = new THREE.ColladaLoader(); 
      loader.options.convertUpAxis = true; 
      loader.load('/site_media/models/model.dae', function (collada) { 
       dae = collada.scene; 
       skin = collada.skins[ 0 ]; 

       dae.scale.x = dae.scale.y = dae.scale.z = 0.90; 
       dae.updateMatrix(); 

       init(el); 
       animate(); 

      }); 

      function init(el) { 

       container = document.createElement('div'); 
       el.append(container); 

       camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 2000); 
       camera.position.set(2, 2, 3); 

       scene = new THREE.Scene(); 


       scene.add(dae); 

       particleLight = new THREE.Mesh(new THREE.SphereGeometry(4, 8, 8), new THREE.MeshBasicMaterial({ color: 0xffffff })); 
       scene.add(particleLight); 

       // Lights 

       scene.add(new THREE.AmbientLight(0xcccccc)); 

       var directionalLight = new THREE.DirectionalLight(/*Math.random() * 0xffffff*/0xeeeeee); 
       directionalLight.position.x = Math.random() - 0.5; 
       directionalLight.position.y = Math.random() - 0.5; 
       directionalLight.position.z = Math.random() - 0.5; 
       directionalLight.position.normalize(); 
       scene.add(directionalLight); 

       // pointLight = new THREE.PointLight(0xffffff, 4); 
       // pointLight.position = particleLight.position; 
       // scene.add(pointLight); 

       renderer = new THREE.WebGLRenderer(); 
       renderer.setSize(window.innerWidth/2, window.innerHeight/2); 


       container.appendChild(renderer.domElement); 

       stats = new Stats(); 
       stats.domElement.style.position = 'absolute'; 
       stats.domElement.style.top = '0px'; 
       container.appendChild(stats.domElement); 

       // 

       window.addEventListener('resize', onWindowResize, false); 

      } 

      function onWindowResize() { 

       camera.aspect = window.innerWidth/window.innerHeight; 
       camera.updateProjectionMatrix(); 

       renderer.setSize(window.innerWidth/2, window.innerHeight/2); 

      } 

      // 

      var t = 0; 
      var clock = new THREE.Clock(); 

      function animate() { 

       var delta = clock.getDelta(); 

       requestAnimationFrame(animate); 

       if (t > 1) t = 0; 

       if (skin) { 

        // guess this can be done smarter... 

        // (Indeed, there are way more frames than needed and interpolation is not used at all 
        // could be something like - one morph per each skinning pose keyframe, or even less, 
        // animation could be resampled, morphing interpolation handles sparse keyframes quite well. 
        // Simple animation cycles like this look ok with 10-15 frames instead of 100 ;) 

        for (var i = 0; i < skin.morphTargetInfluences.length; i++) { 

         skin.morphTargetInfluences[ i ] = 0; 

        } 

        skin.morphTargetInfluences[ Math.floor(t * 30) ] = 1; 

        t += delta; 

       } 

       render(); 
       stats.update(); 

      } 

      function render() { 

       var timer = Date.now() * 0.0005; 

       camera.position.x = Math.cos(timer) * 10; 
       camera.position.y = 2; 
       camera.position.z = Math.sin(timer) * 10; 

       camera.lookAt(scene.position); 

       particleLight.position.x = Math.sin(timer * 4) * 3009; 
       particleLight.position.y = Math.cos(timer * 5) * 4000; 
       particleLight.position.z = Math.cos(timer * 4) * 3009; 

       renderer.render(scene, camera); 

      } 


} 
+0

的可能的複製[如何設置材料three.js所裝載的Collada(DAE)模型時, ?](http://stackoverflow.com/questions/8281681/how-to-setup-materials-in-three-js-when-loading-collada-dae-models) – 2016-12-31 12:43:34

回答

2

經過很多問題,我們在ColladaLoader.js中寫了一個小小的破解,從@gaitat 這個想法中基本取代了舊圖像的紋理,傳遞了一些新的數組,並使用正則表達式在圖片標籤下爲.png或.jpg解析xml。不知道是否有一個更簡單的方法,但由於支持是有限的,我們必須拿出一個固定莫名其妙

function parse(doc, imageReplace, callBack, url) { 

    COLLADA = doc; 
    callBack = callBack || readyCallbackFunc; 

    if (url !== undefined) { 

     var parts = url.split('/'); 
     parts.pop(); 
     baseUrl = (parts.length < 1 ? '.' : parts.join('/')) + '/'; 

    } 

    parseAsset(); 
    setUpConversion(); 
    images = parseLib("//dae:library_images/dae:image", _Image, "image"); 

    for(var i in imageReplace) { 
     var iR = imageReplace[i]; 

     for(var i in images) { 
      var image = images[i]; 

      var patt=new RegExp('[a-zA-Z0-9\-\_]*\/'+iR.name,'g'); 

      //if(image.id==iR.id) 
      if(patt.test(image.init_from)) 
       image.init_from = iR.new_image; 
     }//for 
    } 

    materials = parseLib("//dae:library_materials/dae:material", Material, "material"); 
    effects = parseLib("//dae:library_effects/dae:effect", Effect, "effect"); 
    geometries = parseLib("//dae:library_geometries/dae:geometry", Geometry, "geometry"); 
    cameras = parseLib(".//dae:library_cameras/dae:camera", Camera, "camera"); 
    controllers = parseLib("//dae:library_controllers/dae:controller", Controller, "controller"); 
    animations = parseLib("//dae:library_animations/dae:animation", Animation, "animation"); 
    visualScenes = parseLib(".//dae:library_visual_scenes/dae:visual_scene", VisualScene, "visual_scene"); 

    morphs = []; 
    skins = []; 

    daeScene = parseScene(); 
    scene = new THREE.Object3D(); 

    for (var i = 0; i < daeScene.nodes.length; i ++) { 

     scene.add(createSceneGraph(daeScene.nodes[ i ])); 

    } 

// unit conversion 
scene.position.multiplyScalar(colladaUnit); 
scene.scale.multiplyScalar(colladaUnit); 

    createAnimations(); 

    var result = { 

     scene: scene, 
     morphs: morphs, 
     skins: skins, 
     animations: animData, 
     dae: { 
      images: images, 
      materials: materials, 
      cameras: cameras, 
      effects: effects, 
      geometries: geometries, 
      controllers: controllers, 
      animations: animations, 
      visualScenes: visualScenes, 
      scene: daeScene 
     } 

    }; 

    if (callBack) { 

     callBack(result); 

    } 

    return result; 

}; 
+0

您可以接受您自己的答案。 – WestLangley 2013-02-26 18:11:49

1

一件事你可以做的是修改COLLADA模型(DAE文件)定位紋理參考那裏,它改變自己的喜好。

+0

有點需要動態解決方案 – psychok7 2013-02-22 16:03:36

8

您可以用這種函數遞歸地覆蓋您的collada場景材質。它貫穿整個層次結構並分配材料。

var setMaterial = function(node, material) { 
    node.material = material; 
    if (node.children) { 
    for (var i = 0; i < node.children.length; i++) { 
     setMaterial(node.children[i], material); 
    } 
    } 
} 

使用它像setMaterial(dae, new THREE.MeshBasicMaterial({color: 0xff0000}));

你也許可以適應,要修改,而不是分配一個新的現有材料的性能,如果需要的話。

+0

我應該在哪裏添加這個代碼? – psychok7 2013-02-22 14:54:57

+0

您應該在loader.load回調中調用該函數,以便在加載collada之後分配新材質。實際上,如果您需要動態更改材料,則可以在加載collada後的任何時間執行此操作。功能本身可以去任何地方。 – yaku 2013-02-22 15:01:21

+0

是的,它適用於顏色。這可以爲紋理工作嗎?如果是的話,怎麼樣? – psychok7 2013-02-22 15:21:08

0
if (url !== undefined) { 
    var parts = url.split('/'); 
    parts.pop(); 
    baseUrl = (parts.length < 1 ? '.' : parts.join('/')) + '/'; 

} 

parseAsset(); 
setUpConversion(); 
images = parseLib("//dae:library_images/dae:image", _Image, "image"); 

for(var i in imageReplace) { 
    var iR = imageReplace[i]; 

    for(var i in images) { 
     var image = images[i]; 

     var patt=new RegExp('[a-zA-Z0-9\-\_]*\/'+iR.name,'g'); 

     //if(image.id==iR.id) 
     if(patt.test(image.init_from)) 
      image.init_from = iR.new_image; 
    }//for 
}