Я копаюсь в Three.js и экспериментирую с vrml, а теперь и с файлами collada.

Импорт файла collada работает. Он работает с webGL И холстом в качестве запасного варианта: моя 3D-модель вращается, показывает модель ... а в webGL я могу даже иметь такие замечательные эффекты, как тени, неровности и т. Д.

Мне удалось загрузить другой файл текстуры, назначив его рендереру webGL… но в данном конкретном случае рендерер холста полностью не работает: кадры падают с 60 кадров в секунду до 2 кадров в секунду, а текстура «скользит» по полигонам.

Думаю, я что-то упустил, чтобы «исправить» текстуру в модели, или при импорте текстуры, может быть, я пропускаю какие-то параметры? И снова он работает нормально, не меняя текстуры ... но мне это действительно нужно: p

Вот рабочий превью: http://dokmixer.com/three-tests/

И вот часть, где магия терпит неудачу:

//model loading
      loader = new THREE.ColladaLoader();
      loader.load('models/collada/7cm.005.dae',function colladaReady( collada ){
        player = collada.scene;
        skin = collada.skins [ 0 ];
        player.scale.x = player.scale.y = player.scale.z = 0.10;

        if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
          var newskinTexture = new THREE.ImageUtils.loadTexture( 'models/collada/dokMixer.png' );
          themodel = collada.scene.children[0];
          themodel.material = new THREE.MeshBasicMaterial( { map: newskinTexture, overdraw: true} );
        }
        else {
          var newskinTexture = new THREE.ImageUtils.loadTexture( 'models/collada/dokMixer.png' );
          var bumpTexture = new THREE.ImageUtils.loadTexture( 'models/collada/noise.png' );
          bumpTexture.anisotropy = 2;
          player_material = collada.scene.children[0].material;
          themodel = collada.scene.children[0];
          themodel.material = new THREE.MeshPhongMaterial( { map: newskinTexture, bumpMap: bumpTexture, bumpScale: 0.05} );
        }

        //utile pour avoir les ombres
        daemesh = player.children[0];
        daemesh.castShadow = true;
        daemesh.receiveShadow = true;

        scene.add( player ); 
      });

Часть, на которую нужно обратить внимание, - это первый оператор if (поскольку я тестирую холст с Safari, прежде чем расширяться на другие устройства с поддержкой холста). При назначении нового материала рендерер полностью выходит из строя. Проверить эффект можно, перейдя на страницу с Safari.

Примечание: я работаю над OSX, если это может быть какой-либо соответствующей информацией.

Любая помощь приветствуется :)

РЕДАКТИРОВАТЬ: я думаю, я устанавливаю здесь новый материал, вместо того, чтобы заменять только исходный файл изображения?

2
dokMixer 16 Янв 2014 в 00:09

1 ответ

Лучший ответ

Хорошо, наконец-то нашел обходной путь!

То, как я поменял местами текстуру, было неправильным для холста, я предполагаю, что это ошибка. Я нашел ответ на этот вопрос от psychok7 < / а>.

Итак, вместо загрузки и ТОГО изменения текстуры ... я изменил код в файле ColladaLoader.js. Ну почти то же самое. Поскольку я использую «load», я пару раз добавил imageReload в функции загрузки и при вызове функции «parse». Затем в функции синтаксического анализа я также внес некоторые изменения, поскольку приведенный код был неправильным в их ссылке. Для заинтересованных - список изменений и мой окончательный код. К сожалению, я не смог достичь «тех же» функций (отправка массива текстур, выполнение функции regExp и одновременная замена нескольких текстур), эта часть была для меня ошибочной, и поскольку мне нужно было изменить только один файл текстуры ...

  • я не делаю iamge.init_from = iR.new_image; в материале цикла regExp… но вместо этого добавьте image.init_from = iR; непосредственно перед параметром regExp.
  • При вызове функции в моем файле я отправляю массив… он не был задокументирован, не имел примеров, и мне было трудно его понять. Что ж, не пытайтесь напрямую отправить URL-адрес .png или .jpeg, поместите эти имена в таблицу перед и в вызове функции этого массива. Не забудьте удалить пути, так как это должен быть тот же путь, который описан ВНУТРИ вашего файла collada (так что в моем случае просто имя текстуры, поскольку мой файл collada находится в той же папке, что и текстуры).
  • в коде psychok явно была ошибка в вызовах "parseLib", где он пишет такие вещи, как parseLib ("// dae: library_materials / dae: material", Material, "material"); вместо parseLib ("материал_библиотеки", Материал, "материал"); (который работает и является исходным кодом).

Итак, вкратце, вот код, в котором я называю колладу

 loader = new THREE.ColladaLoader();
      newtextures = ['dokMixer.png'];
      loader.load('models/collada/7cm.005.dae', newtextures,function colladaReady( collada ){
        player = collada.scene;
        skin = collada.skins [ 0 ];
        player.scale.x = player.scale.y = player.scale.z = 0.10;

        //i'll add code here later for extra bump mapping on webgl versions

        //usefull for shadows on webgl version
        daemesh = player.children[0];
        daemesh.castShadow = true;
        daemesh.receiveShadow = true;

        scene.add( player ); 
      });

А вот код внутри colladaLoader. Это замена функций load и parse.

function load ( url, imageReplace, readyCallback, progressCallback ) {

    var length = 0;

    if ( document.implementation && document.implementation.createDocument ) {

        var request = new XMLHttpRequest();

        request.onreadystatechange = function() {

            if( request.readyState == 4 ) {

                if( request.status == 0 || request.status == 200 ) {


                    if ( request.responseXML ) {

                        readyCallbackFunc = readyCallback;
                        parse( request.responseXML, imageReplace, undefined, url );

                    } else if ( request.responseText ) {

                        readyCallbackFunc = readyCallback;
                        var xmlParser = new DOMParser();
                        var responseXML = xmlParser.parseFromString( request.responseText, "application/xml" );
                        parse( responseXML, imageReplace, undefined, url );

                    } else {

                        console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" );

                    }

                }

            } else if ( request.readyState == 3 ) {

                if ( progressCallback ) {

                    if ( length == 0 ) {

                        length = request.getResponseHeader( "Content-Length" );

                    }

                    progressCallback( { total: length, loaded: request.responseText.length } );

                }

            }

        }

        request.open( "GET", url, true );
        request.send( null );

    } else {

        alert( "Don't know how to parse 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( "library_images image", _Image, "image" );

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

        for(var i in images) {
            var image = images[i];
            //added line, but no multiple textures !
            image.init_from = iR; 

            //RegExp and patt.test not working
            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( "library_materials material", Material, "material" );
    effects = parseLib( "library_effects effect", Effect, "effect" );
    geometries = parseLib( "library_geometries geometry", Geometry, "geometry" );
    cameras = parseLib( "library_cameras camera", Camera, "camera" );
    lights = parseLib( "library_lights light", Light, "light" );
    controllers = parseLib( "library_controllers controller", Controller, "controller" );
    animations = parseLib( "library_animations animation", Animation, "animation" );
    visualScenes = parseLib( "library_visual_scenes visual_scene", VisualScene, "visual_scene" );
    // 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;

}

Надеюсь, это кому-то поможет! Развлекайся ! :)

1
Community 23 Май 2017 в 15:03