zoukankan      html  css  js  c++  java
  • 这不是我心目中的比目猪!快来看看这只3D小猪佩奇!

    小猪佩奇总是用侧脸示人,不论是转左边还是转右边,脸上总是有2只眼睛、2个鼻孔、1腮红,小手手不断挥呀挥,讲完一句话就要发出猪叫声,最爱在往泥巴坑里跳。

    佩奇正脸也是相当神秘,从未用“正脸”示人,引起许多人好奇心。作为一个负责任的3D可视化厂商,在猪年春节来临之际ThingJS特意制作了一个3D粒子特效的小猪佩奇!

    开来看看佩奇正脸到底长成什么样子!


    点我看佩奇!


     
     

    源码(复制到ThingJS在线开发平台即可运行):
    document.title = "ThingJS祝您猪年大吉-3D应用开发选ThingJS-优锘科技";
    THING.Utils.dynamicLoadJS(['http://darsa.in/fpsmeter/js/fpsmeter.min.js'], function () {
        //variables----
        var app = new THING.App({
            forceWebGL1: true
        });
        var fpsMeter = new FPSMeter();
        var bEnableEgg = true;
        var modelA = null;
        var modelB = null;
        var modelEgg = null;
        var pointCloudMeshAnimator = null;
        var pointCloudMeshAnimatorEgg = null;
        var pointCloud = null;
        var pointCloudEgg = null;
        var bTransforming = false;
        var bEggShowing = false;
        var fScaleMax = 1.5;
        var fScaleMulit = 1.0;
        var fScaleClickStep = 0.05;
        var fScaleTimeStep = -0.001;
        var bMute = true;
        var listener = null;
        var audioBuffer_Fireworks = null;
        var audioBuffer_Background = null;
        var bIsAudioBackgroundPlaying = false;
        var iAudioBuffer_FireworksIndex = 0;
        var texturePoint = null;
        var textureFireworks = null;
        var fireworksArray = new Array();
    
        var colorFireworksArray = [
            0xf5f5dc,
            0xfafad2,
            0xffffe0,
            0xf0e68c,
            0xffd700,
            0xfff8dc,
            0xdaa520,
            0xffa500,
            0xffefD5,
            0xff7f50,
            0xff4500,
            0xffb6c1,
            0xffc0cb
        ];
        //----variables
    
        //main loop----
        setUI();
        initEnv();
        initAudioListener();
        initAudio_Background();
        initAudio_Fireworks();
        addTouchListener();
    
        initModels(function () {
            app.camera.position = [100, 00, 150];
            app.camera.target = [0, 0, 0];
    
            CreatePointCloud(function () {
                console.log("[CreatePointCloud] called finished;");
    
                setTimeout(function(){
                    bTransforming = true;
                    doTransformLoop();
                }, 3000);
            });
        });
    
        // update浜嬩欢
        app.on('update', function () {
            onTick();
        });
    
        app.on('click', function (e) {
            if (!app.isMobileDevice) {
                console.log("[onClick]; bEggShowing = " + bEggShowing);
    
                if (!bEggShowing) {
                    playFireworks();
                    fScaleMulit += fScaleClickStep;
    
                    if (fScaleMulit >= fScaleMax) {
                        fScaleMulit = 1.0;
                        if (bEnableEgg) {
                            playEgg(function () {
                                hideEgg();
                            });
                        }
                    }
                }
            }
        });
    
        //----main loop
    
        //functions----
        // 娣诲姞html
        function setUI() {
            setUIBackground();
            setUIVolume();
        }
    
        function setUIVolume() {
            var sign = `<div id='sign' data-type="" style=" 40px;height: 40px;background: url('https://thingjs.com/static/particles/Assets/mute.png') no-repeat;background-size: contain;position: absolute;top: 20px;right: 20px;cursor: pointer;border-radius:50%"></div>`;
            $('#content').append($(sign));
            $('#sign').click(function () {
                var type = $(this).attr('data-type');
                if (type == 'checked') {
                    $(this).css({ 'backgroundImage': 'url(https://thingjs.com/static/particles/Assets/mute.png)', })
                    $(this).attr('data-type', '');
                    bMute = true;
                    setSound(bMute);
                } else {
                    $(this).css({ 'backgroundImage': 'url(https://thingjs.com/static/particles/Assets/volume.png)', })
                    $(this).attr('data-type', 'checked');
                    bMute = false;
                    setSound(bMute);
                }
            });
        }
    
        function setUIBackground() {
            $(document.body).css({
                'backgroundImage': !app.isMobileDevice ? 'url(http://www.thingjs.com/uploads/wechat/oLX7p0-0atbpF5ckWc4QiVYPuxV8/file/2019/pig-pc.jpg)' : "url('http://www.thingjs.com/uploads/wechat/oLX7p0-0atbpF5ckWc4QiVYPuxV8/file/2019/pig-m.jpg')",
                'backgroundRepeat': 'no-repeat',
                'backgroundPosition': 'center top',
                'backgroundSize': 'cover'
            });
            $('#div3d').css('background', 'none');
        }
    
        function initEnv() {
            console.log("[initEnv];");
    
            app.background = 0x000000;
            app.camera.enablePan = false;
            app.camera.enableZoom = false;
            fpsMeter.hide();
        }
    
        function initModels(onFinished) {
            console.log("[initModels];");
    
            var bModelACreated = false;
            var bModelBCreated = false;
            var bModelEggCreated = false;
            modelA = app.create({
                type: 'Thing',
                name: 'Piggy',
                url: 'http://model.3dmomoda.com/models/22e0c9d763d4474288555435f250e2ba/0/gltf/',
                position: [0, 0, 30],
                angle: 0,
                complete: function () {
                    console.log('[initModels] : thing created: ' + this.id);
                    bModelACreated = true;
                    if (bModelACreated && bModelBCreated && bModelEggCreated) {
                        onFinished();
                    }
                }
            });
    
            modelA.rotateX(-90);
            modelA.scale = [20, 20, 20];
            modelA.visible = false;
    
            modelB = app.create({
                type: 'Thing',
                name: 'Fu',
                url: 'http://model.3dmomoda.com/models/933d3a29404948798334336bdfd20c57/0/gltf/',
                position: [0, 30, 10],
                angle: 0,
                complete: function () {
                    console.log('[initModels] : thing created: ' + this.id);
                    bModelBCreated = true;
                    if (bModelACreated && bModelBCreated && bModelEggCreated) {
                        onFinished();
                    }
                }
            });
    
            modelB.rotateX(-90);
            modelB.rotateZ(30);
            modelB.scale = [0.3, 0.3, 0.3];
            modelB.visible = false;
    
            modelEgg = app.create({
                type: 'Thing',
                name: 'Logo',
                url: 'http://model.3dmomoda.com/models/ac9f2476dad14fc1aee321512bd908b2/0/gltf/',
                position: [0, 0, 0],
                angle: 0,
                complete: function () {
                    console.log('[initModels] : thing created: ' + this.id);
                    bModelEggCreated = true;
                    if (bModelACreated && bModelBCreated && bModelEggCreated) {
                        onFinished();
                    }
                }
            });
    
            modelEgg.rotateX(-90);
            modelEgg.scale = [60, 60, 60];
            modelEgg.visible = false;
        }
    
        function CreatePointCloud(onFinished) {
            console.log("[CreatePointCloud];");
    
            var dataVo = new Array();
            var iAnimateIndexArray = new Array();
    
            var dvA =
            {
                "object": modelA.node,
                "position": new THREE.Vector3(
                    modelA.node.position.x,
                    modelA.node.position.y,
                    modelA.node.position.z),
    
                "scale": new THREE.Vector3(
                    modelA.node.scale.x,
                    modelA.node.scale.y,
                    modelA.node.scale.z),
    
                "quat": new THREE.Vector4(
                    modelA.node.quaternion.x,
                    modelA.node.quaternion.y,
                    modelA.node.quaternion.z,
                    modelA.node.quaternion.w),
    
                "step": 0.02
            };
            dataVo.push(dvA);
            iAnimateIndexArray.push(0);
    
            var dvB =
            {
                "object": modelB.node,
                "position": new THREE.Vector3(
                    modelB.node.position.x,
                    modelB.node.position.y,
                    modelB.node.position.z),
    
                "scale": new THREE.Vector3(
                    modelB.node.scale.x,
                    modelB.node.scale.y,
                    modelB.node.scale.z),
    
                "quat": new THREE.Vector4(
                    modelB.node.quaternion.x,
                    modelB.node.quaternion.y,
                    modelB.node.quaternion.z,
                    modelB.node.quaternion.w),
                "step": 0.02
            };
    
            dataVo.push(dvB);
            iAnimateIndexArray.push(1);
    
            var manager = new THREE.LoadingManager();
            manager.onProgress = function (item, loaded, total) {
                console.log(item, loaded, total);
            };
            var textureLoader = new THREE.TextureLoader(manager);
            var strTexturePath = "https://thingjs.com/static/particles/Assets/boom.png";
            texturePoint = textureLoader.load(strTexturePath);
    
            var material = new THREE.PointsMaterial({
                color: 0xdaa520,
                size: 2,
                transparent: true,
                blending: THREE.AdditiveBlending,
                depthTest: false,
                map: texturePoint
            });
    
            var params =
            {
                "dataVoArray": dataVo,
                "animateIndexArray": iAnimateIndexArray,
                "material": material
            };
    
            pointCloudMeshAnimator = new PointCloudMeshAnimator();
            pointCloudMeshAnimator.Init(
                params,
                function (pc) {
                    if (pc != null && pc != undefined) {
                        pointCloud = pc;
                        app.scene.add(pc);
                    }
                    onFinished();
                }
            );
    
            var dataVoEgg = new Array();
            var iAnimateIndexArrayEgg = new Array();
    
            var dvEgg =
            {
                "object": modelEgg.node,
                "position": new THREE.Vector3(
                    modelEgg.node.position.x,
                    modelEgg.node.position.y,
                    modelEgg.node.position.z),
    
                "scale": new THREE.Vector3(
                    modelEgg.node.scale.x,
                    modelEgg.node.scale.y,
                    modelEgg.node.scale.z),
    
                "quat": new THREE.Vector4(
                    modelEgg.node.quaternion.x,
                    modelEgg.node.quaternion.y,
                    modelEgg.node.quaternion.z,
                    modelEgg.node.quaternion.w),
    
                "step": 0.02
            };
            dataVoEgg.push(dvA);
            iAnimateIndexArrayEgg.push(0);
    
            dataVoEgg.push(dvEgg);
            iAnimateIndexArrayEgg.push(1);
    
            var paramsEgg =
            {
                "dataVoArray": dataVoEgg,
                "animateIndexArray": iAnimateIndexArrayEgg,
                "material": material
            };
    
            pointCloudMeshAnimatorEgg = new PointCloudMeshAnimator();
            pointCloudMeshAnimatorEgg.Init(
                paramsEgg,
                function (pc) {
                    if (pc != null && pc != undefined) {
                        pointCloudEgg = pc;
                        app.scene.add(pc);
                        pointCloudEgg.visible = false;
                    }
                }
            );
        };
    
        function doTransformLoop() {
            if (
                bTransforming
                && pointCloudMeshAnimator != null
                && pointCloudMeshAnimator != undefined
            ) {
                pointCloudMeshAnimator.DoAnimation(
                    function () {
                        setTimeout(doTransformLoop, 3000);
                    }
                );
            }
        }
    
        function doTransformLoopEgg() {
            if (
                bEggShowing
                && pointCloudMeshAnimatorEgg != null
                && pointCloudMeshAnimatorEgg != undefined
            ) {
                pointCloudMeshAnimatorEgg.DoAnimation(
                    function () {
                        setTimeout(doTransformLoopEgg, 3000);
                    }
                );
            }
        }
    
        function onTick() {
            fpsMeter.tick();
            if (pointCloudMeshAnimator != null && pointCloudMeshAnimator != undefined) {
                if (fpsMeter != null && fpsMeter != undefined)
                    pointCloudMeshAnimator.Tick(fpsMeter.fps);
                else
                    pointCloudMeshAnimator.Tick(30.0);
            }
    
            if (bEggShowing && pointCloudMeshAnimatorEgg != null && pointCloudMeshAnimatorEgg != undefined) {
                if (fpsMeter != null && fpsMeter != undefined)
                    pointCloudMeshAnimatorEgg.Tick(fpsMeter.fps);
                else
                    pointCloudMeshAnimatorEgg.Tick(30.0);
            }
    
            if (fScaleMulit > 1.0)
                fScaleMulit += fScaleTimeStep;
    
            if (pointCloud != null && pointCloud != undefined) {
                pointCloud.scale.x = fScaleMulit;
                pointCloud.scale.y = fScaleMulit;
                pointCloud.scale.z = fScaleMulit;
            }
    
            tickFireworks();
        }
    
        function playEgg(onFinished) {
            console.log("[playEgg];");
    
            if (bEggShowing)
                return;
    
            bEggShowing = true;
    
            if (pointCloud != null && pointCloud != undefined)
                pointCloud.visible = false;
    
            if (pointCloudEgg != null && pointCloudEgg != undefined) {
                pointCloudEgg.visible = true;
                doTransformLoopEgg();
            }
    
            setTimeout(function () {
                if (pointCloudEgg != null && pointCloudEgg != undefined) {
                    pointCloudEgg.visible = false;
                }
                if (pointCloud != null && pointCloud != undefined)
                    pointCloud.visible = true;
                onFinished();
            }, 12000);
        }
    
        function hideEgg() {
            console.log("[hideEgg];");
            bEggShowing = false;
        }
    
        function initAudioListener() {
            console.log("[initAudioListener];");
            listener = new THREE.AudioListener();
            app.renderCamera.add(listener);
        }
    
        function initAudio_Background() {
            console.log("[initAudio_Background];");
            if (listener == null || listener == undefined) {
                console.error("[initAudio_Background] : check your listener;");
                return;
            }
    
            var strUrlAudio = "https://thingjs.com/static/particles/Assets/mp3/happy_new_year.mp3";
            if (!app.isMobileDevice) {
                audioBuffer_Background = new THREE.Audio(listener);
                var audioLoader = new THREE.AudioLoader();
                audioLoader.load(strUrlAudio, function (buffer) {
                    audioBuffer_Background.setBuffer(buffer);
                    audioBuffer_Background.setLoop(true);
                    audioBuffer_Background.setVolume(0.5);
                    audioBuffer_Background.play();
                    setSound(bMute);
                });
            }
            else {
                audioBuffer_Background = new WebAudio();
                audioBuffer_Background._init({
                    src: strUrlAudio,
                    autoPlay: true,
                    loop: true,
                    onUpdatetime: function (e) {
                        //console.log("[initAudio_Background] : onUpdatetime : " + audioBuffer_Background.audio.currentTime);
                    }
                });
                audioBuffer_Background.load();
                setSound(bMute);
            }
        }
    
        function initAudio_Fireworks() {
            console.log("[initAudio_Fireworks];");
            if (listener == null || listener == undefined) {
                console.error("[initAudio_Fireworks] : check your listener;");
                return;
            }
    
            var strUrlAudio = "https://thingjs.com/static/particles/Assets/mp3/fireworks_explosion.mp3";
            if (!app.isMobileDevice) {
                var audioLoader = new THREE.AudioLoader();
                audioLoader.load(strUrlAudio, function (buffer) {
                    audioBuffer_Fireworks = buffer;
                });
            }
            else {
                audioBuffer_Fireworks = new Array();
    
                for (var i = 0; i < 10; i++) {
                    var abf = new WebAudio();
                    abf._init({
                        src: strUrlAudio,
                        onUpdatetime: function (e) {
                        }
                    });
                    abf.load();
                    audioBuffer_Fireworks.push(abf);
                }
            }
        }
    
        function addTouchListener() {
            console.log("[addTouchListener];");
            if (app.isMobileDevice) {
                document.addEventListener("touchstart", function () {
                    if (
                        !bIsAudioBackgroundPlaying
                        && audioBuffer_Background != null
                        && audioBuffer_Background != undefined
                    ) {
    
                        bIsAudioBackgroundPlaying = true;
                        audioBuffer_Background.play();
                        setSound(bMute);
                    }
    
                    if (!bMute && !bEggShowing)
                        playAudio_Fireworks_Mobile();
    
                    if (!bEggShowing) {
                        playFireworks();
                        fScaleMulit += fScaleClickStep;
    
                        if (fScaleMulit >= fScaleMax) {
                            fScaleMulit = 1.0;
    
                            if (bEnableEgg) {
                                playEgg(function () {
                                    hideEgg();
                                });
                            }
                        }
                    }
    
                }, false);
            }
        }
    
        function playAudio_Fireworks_PC() {
            if (audioBuffer_Fireworks == null || audioBuffer_Fireworks == undefined) {
                console.error("[playAudio_Fireworks_PC] : check your audioBuffer_Fireworks;");
                return;
            }
    
            var sound = new THREE.Audio(listener);
            sound.setBuffer(audioBuffer_Fireworks);
            sound.setLoop(false);
            sound.setVolume(0.8);
            sound.play();
        }
    
        function playAudio_Fireworks_Mobile() {
            if (audioBuffer_Fireworks == null || audioBuffer_Fireworks == undefined) {
                console.error("[playAudio_Fireworks_Mobile] : check your audioBuffer_Fireworks;");
                return;
            }
    
            iAudioBuffer_FireworksIndex++;
            if (iAudioBuffer_FireworksIndex >= audioBuffer_Fireworks.length)
                iAudioBuffer_FireworksIndex = 0;
    
            audioBuffer_Fireworks[iAudioBuffer_FireworksIndex].play();
        }
    
        function playFireworks() {
            console.log("[playFireworks];");
    
            var geometryFireBall = new THREE.Geometry();
    
            for (var i = 0; i < 1; i++) {
                var pos = new THREE.Vector3();
                pos.x = 0;
                pos.y = 0;
                pos.z = 0;
                geometryFireBall.vertices.push(pos);
            }
    
            if (textureFireworks == null || textureFireworks == undefined) {
                var manager = new THREE.LoadingManager();
                manager.onProgress = function (item, loaded, total) {
                    console.log(item, loaded, total);
                };
                var textureLoader = new THREE.TextureLoader(manager);
                var strTexturePath = "https://thingjs.com/static/particles/Assets/fireworks_0.png";
                textureFireworks = textureLoader.load(strTexturePath);
            }
            var color = colorFireworksArray[THREE.Math.randInt(0, colorFireworksArray.length - 1)];
            var materialFireBall = new THREE.PointsMaterial({
                color: color,
                size: 10,
                transparent: true,
                blending: THREE.AdditiveBlending,
                depthTest: false,
                map: textureFireworks
            });
    
            var meshFireBall = new THREE.Points(geometryFireBall, materialFireBall);
            app.scene.add(meshFireBall);
    
            var fireworks = new Fireworks();
            fireworksArray.push(fireworks);
            fireworks.Init({
                "fireBall": meshFireBall,
                "speed": 6.5,
                "speedSpread": 0.05,
                "acc": -0.1,
                "accSpread": 0.02,
                "bomb": THREE.Math.randFloat(20.0, 50.0),
                "life": 1000,
                "t": 1
            }, function () {
                fireworks.TriggerBomb();
                setTimeout(function () {
                    app.scene.remove(meshFireBall);
                }, 100);
            });
    
            if (!bMute)
                playAudio_Fireworks_PC();
        }
    
        function tickFireworks() {
            for (var i = 0, iLen = fireworksArray.length; i < iLen; i++) {
                fireworksArray[i].Tick();
                if (!fireworksArray.bIsRunning) {
                    fireworksArray.slice(i, 1);
                    iLen = fireworksArray.length;
                }
            }
        }
    
        function setSound(bMute) {
            if (bMute)
                audioBuffer_Background.pause();
            else
                audioBuffer_Background.play();
        }
    });
    //----functions
    
    //Class Fireworks----
    Fireworks = function () {
        var strLogHead = "[Fireworks.js] : ";
        var bEnableLog = true;
    
        var bounds =
        {
            "minX": -50.0,
            "maxX": 50.0,
    
            "minY": -200.0,
            "maxY": -100.00,
    
            "minZ": -50.0,
            "maxZ": 50.0,
        };
    
        this.meshFireBall = null;
        this.particleFireworks = null;
        this.bIsRunning = true;
        this.bIsBombing = false;
        this.vec3InitPos = null;
        this.vec3Pos = null;
        this.fSpeed = 10;
        this.fBomb = 10;
        this.fAcc = 1;
        this.fT = 0.01;
    
        this.fTime = 0;
        var scope = this;
    
        //public functions----
        this.Init = function (params, onFinished) {
            if (bEnableLog)
                console.log(strLogHead + "[Init];");
    
            if (onFinished == null || onFinished == undefined) {
                console.error(strLogHead + "[Init] : onFinished must be setted;");
                return;
            }
    
            if (params == null || params == undefined) {
                console.error(strLogHead + "[Init] : params must be setted;");
                onFinished(null);
                return;
            }
            else {
                if (params.fireBall == null || params.fireBall == undefined) {
                    console.error(strLogHead + "[Init] : params.fireBall must be setted;");
                    onFinished(null);
                    return;
                }
    
                scope.meshFireBall = params.fireBall;
                scope.vec3InitPos = new THREE.Vector3(
                    THREE.Math.randFloat(bounds.minX, bounds.maxX),
                    THREE.Math.randFloat(bounds.minY, bounds.maxY),
                    THREE.Math.randFloat(bounds.minZ, bounds.maxZ)
                );
                scope.vec3Pos = scope.vec3InitPos.clone();
    
                scope.meshFireBall.position.x = scope.vec3InitPos.x;
                scope.meshFireBall.position.y = scope.vec3InitPos.y;
                scope.meshFireBall.position.z = scope.vec3InitPos.z;
    
                var fLife = 1000;
                if (params.life == null || params.life == undefined) {
                    console.warn(strLogHead + "[Init] : params.life is not setted; use default life;");
                }
                else
                    fLife = params.life;
    
                scope.fSpeed = 10;
                if (params.speed == null || params.speed == undefined) {
                    console.warn(strLogHead + "[Init] : params.speed is not setted; use default speed;");
                }
                else
                    scope.fSpeed = params.speed;
    
                scope.fAcc = 1;
                if (params.acc == null || params.acc == undefined) {
                    console.warn(strLogHead + "[Init] : params.acc is not setted; use default acc;");
                }
                else
                    scope.fAcc = params.acc;
    
                scope.fBomb = 10;
                if (params.bomb == null || params.bomb == undefined) {
                    console.warn(strLogHead + "[Init] : params.bomb is not setted; use default bomb;");
                }
                else
                    scope.fBomb = params.bomb;
    
                var fSpeedSpread = 1;
                if (params.speedSpread == null || params.speedSpread == undefined) {
                    console.warn(strLogHead + "[Init] : params.speedSpread is not setted; use default speedSpread;");
                }
                else
                    fSpeedSpread = params.speedSpread;
    
                var fAccSpread = 1;
                if (params.accSpread == null || params.accSpread == undefined) {
                    console.warn(strLogHead + "[Init] : params.accSpread is not setted; use default accSpread;");
                }
                else
                    fAccSpread = params.accSpread;
    
                scope.fT = 0.01;
                if (params.t == null || params.t == undefined) {
                    console.warn(strLogHead + "[Init] : params.t is not setted; use default t;");
                }
                else
                    scope.fT = params.t;
    
                scope.fSpeed = THREE.Math.randFloat(scope.fSpeed - fSpeedSpread, scope.fSpeed + fSpeedSpread);
                scope.fAcc = THREE.Math.randFloat(scope.fAcc - fAccSpread, scope.fAcc + fAccSpread);
                scope.fTime = 0;
                scope.__initParticleFireworks(function () {
                    scope.bIsRunning = true;
                    setTimeout(function () {
                        scope.bIsRunning = false;
                        onFinished();
                        scope.__playParticleFireworks(function () {
    
                        });
    
                    }, fLife);
                });
            }
        };
    
        this.Tick = function (t) {
            if (scope.bIsRunning && scope.meshFireBall) {
                scope.fTime += scope.fT;
                var t = scope.fTime;
                var v = scope.fSpeed;
                var a = scope.fAcc;
                scope.vec3Pos.y = scope.vec3InitPos.y + v * t + 0.5 * a * t * t;
                scope.meshFireBall.position.y = scope.vec3Pos.y;
            }
    
            if (scope.bIsBombing) {
                scope.fTime += scope.fBomb;
                var s = scope.fTime;
                scope.meshFireBall.material.size = s;
                scope.meshFireBall.material.needUpdate = true;
            }
        };
    
        this.TriggerBomb = function () {
            scope.bIsBombing = true;
            scope.fTime = 0;
        }
    
        this.Uninit = function () {
            if (bEnableLog)
                console.log(strLogHead + "[Uninit];");
        }
        //----public functions
    
        //private functions----
        this.__initParticleFireworks = function (onFinished) {
            if (bEnableLog)
                console.log(strLogHead + "[__initParticleFireworks];");
    
            if (onFinished == null || onFinished == undefined) {
                console.error(strLogHead + "[__initParticleFireworks] : onFinished must be setted;");
                return;
            }
    
            onFinished();
        };
    
        this.__playParticleFireworks = function (onFinished) {
            if (bEnableLog)
                console.log(strLogHead + "[__playParticleFireworks];");
    
            if (onFinished == null || onFinished == undefined) {
                console.error(strLogHead + "[__playParticleFireworks] : onFinished must be setted;");
                return;
            }
    
            onFinished();
        };
        //----private functions
    }
    //----Class Fireworks
    
    //Class PointCloudMeshAnimator----
    PointCloudMeshAnimator = function () {
        var DataVo =
        {
            "iTotalPointCount": 0,
            "fStep": 0.01,
            "position": new THREE.Vector3(0, 0, 0),
            "scale": new THREE.Vector3(1, 1, 1),
            "quat": new THREE.Vector4(0, 0, 0, 1),
            "objectPoints": null,
            "geometry": null
        };
        var strLogHead = "[PointCloudMeshAnimator.js] : ";
        var bEnableLog = true;
        this.iAnimateIndex = 0;
        this.bIsTransforming = false;
        this.fLerp = 0;
        this.pointCloud = null;
        this.material = null;
        this.dataVoArray = new Array();
        this.iAnimateIndexArray = new Array();
    
        this.onTriggerDoAnimationFinished = null;
        var scope = this;
    
        //public functions----
        // var DataVo =
        // {
        //     "object": ,
        //     "position": new THREE.Vector3(0, 0, 0),
        //     "scale": new THREE.Vector3(0, 0, 0),
        //     "quat": new THREE.Vector4(0, 0, 0, 1),
        //      "step": 0.01
        // };
        //@dataVoArray;
        //@material;
        this.Init = function (params, onFinished) {
            if (bEnableLog)
                console.log(strLogHead + "[Init];");
    
            if (onFinished == null || onFinished == undefined) {
                console.error(strLogHead + "[Init] : onFinished must be setted;");
                return;
            }
    
            if (params == null || params == undefined) {
                console.error(strLogHead + "[Init] : params must be setted;");
                onFinished(null);
                return;
            }
            else {
                if (params.dataVoArray == null || params.dataVoArray == undefined || params.dataVoArray.length <= 0) {
                    console.error(strLogHead + "[Init] : params.dataVoArray must be setted;");
                    onFinished(null);
                    return;
                }
    
                for (var i = 0, iLen = params.dataVoArray.length; i < iLen; i++) {
                    var objectA;
                    var objectB;
                    if (params.dataVoArray[i].object == null || params.dataVoArray[i].object == undefined) {
                        console.error(strLogHead + "[Init] : params.dataVoArray[" + i + "].object must be setted;");
                        onFinished(null);
                        return;
                    }
                }
    
                scope.Uninit();
    
                if (params.animateIndexArray == null || params.animateIndexArray == undefined || params.animateIndexArray.length <= 0) {
                    console.warn(strLogHead + "[Init] : params.animateIndexArray is not setted; use default animateIndexArray;");
                    for (var i = 0, iLen = params.dataVoArray.length; i < iLen; i++) {
                        scope.iAnimateIndexArray.push(i);
                    }
                }
                else {
                    scope.iAnimateIndexArray = params.animateIndexArray;
                }
    
    
                for (var i = 0, iLen = params.dataVoArray.length; i < iLen; i++) {
                    var dataVo =
                    {
                        "iTotalPointCount": 0,
                        "fStep": 0.01,
                        "position": new THREE.Vector3(0, 0, 0),
                        "scale": new THREE.Vector3(1, 1, 1),
                        "quat": new THREE.Vector4(0, 0, 0, 1),
                        "objectPoints": null,
                        "geometry": null
                    };
    
                    if (params.dataVoArray[i].position == null || params.dataVoArray[i].position == undefined) {
                        console.warn(strLogHead + "[Init] : params.dataVoArray[" + i + "].position is not setted; use default position;");
                    }
                    else
                        dataVo.position = params.dataVoArray[i].position;
    
                    if (params.dataVoArray[i].scale == null || params.dataVoArray[i].scale == undefined) {
                        console.warn(strLogHead + "[Init] : params.dataVoArray[" + i + "].scale is not setted; use default scale;");
                    }
                    else
                        dataVo.scale = params.dataVoArray[i].scale;
    
                    if (params.dataVoArray[i].quat == null || params.dataVoArray[i].quat == undefined) {
                        console.warn(strLogHead + "[Init] : params.dataVoArray[" + i + "].quat is not setted; use default quat;");
                    }
                    else
                        dataVo.quat = params.dataVoArray[i].quat.normalize();
    
                    if (params.dataVoArray[i].step == null || params.dataVoArray[i].step == undefined) {
                        console.warn(strLogHead + "[Init] : params.dataVoArray[" + i + "].step is not setted; use default step;");
                    }
                    else
                        dataVo.fStep = params.dataVoArray[i].step;
    
                    var iLoadChildIndex = -1;
    
                    if (params.dataVoArray[i].loadIndex == null || params.dataVoArray[i].loadIndex == undefined) {
                        console.warn(strLogHead + "[Init] : params.dataVoArray[" + i + "].loadIndex is not setted; load all children;");
                    }
                    else
                        iLoadChildIndex = params.dataVoArray[i].loadIndex;
    
                    var x = 0;
                    var y = 0;
                    var z = 0;
    
                    var iTotalObjectCount = 0;
                    dataVo.objectPoints = new Array();
                    if (i == 0) {
                        dataVo.geometry = new THREE.Geometry();
                        var iChildIndex = 0;
                        params.dataVoArray[i].object.traverse(function (child) {
                            if (child instanceof THREE.Mesh) {
    
                                if (iLoadChildIndex == -1 || iLoadChildIndex == iChildIndex) {
                                    var positions = child.geometry.attributes.position.array;
    
                                    var index = 0;
                                    var tmpPos;
                                    iTotalObjectCount += child.geometry.attributes.position.count;
                                    for (var i = 0, iLen = child.geometry.attributes.position.count; i < iLen; i++) {
                                        x = positions[index++] * dataVo.scale.x + dataVo.position.x;
                                        y = positions[index++] * dataVo.scale.y + dataVo.position.y;
                                        z = positions[index++] * dataVo.scale.z + dataVo.position.z;
    
                                        tmpPos = new THREE.Vector3(x, y, z);
                                        tmpPos = tmpPos.applyQuaternion(dataVo.quat);
                                        x = tmpPos.x;
                                        y = tmpPos.y;
                                        z = tmpPos.z;
    
                                        dataVo.objectPoints.push(x);
                                        dataVo.objectPoints.push(y);
                                        dataVo.objectPoints.push(z);
    
                                        dataVo.geometry.vertices.push(
                                            new THREE.Vector3(x, y, z)
                                        );
                                    }
                                }
                                iChildIndex++;
                            }
                        });
                    }
                    else {
                        var iChildIndex = 0;
                        params.dataVoArray[i].object.traverse(function (child) {
                            if (child instanceof THREE.Mesh) {
                                if (iLoadChildIndex == -1 || iLoadChildIndex == iChildIndex) {
                                    var positions = child.geometry.attributes.position.array;
                                    var index = 0;
                                    var tmpPos;
                                    iTotalObjectCount += child.geometry.attributes.position.count;
                                    for (var i = 0, iLen = child.geometry.attributes.position.count; i < iLen; i++) {
                                        x = positions[index++] * dataVo.scale.x + dataVo.position.x;
                                        y = positions[index++] * dataVo.scale.y + dataVo.position.y;
                                        z = positions[index++] * dataVo.scale.z + dataVo.position.z;
    
                                        tmpPos = new THREE.Vector3(x, y, z);
                                        tmpPos = tmpPos.applyQuaternion(dataVo.quat);
                                        x = tmpPos.x;
                                        y = tmpPos.y;
                                        z = tmpPos.z;
    
                                        dataVo.objectPoints.push(x);
                                        dataVo.objectPoints.push(y);
                                        dataVo.objectPoints.push(z);
                                    }
                                }
                                iChildIndex++;
                            }
                        });
                    }
                    dataVo.iTotalPointCount = iTotalObjectCount;
                    scope.dataVoArray.push(dataVo);
                }
    
                var iMaxObjectCount = 0;
                for (var i = 0, iLen = scope.dataVoArray.length; i < iLen; i++) {
                    console.log(strLogHead + "[" + i + "]" + " mesh vertexs = " + scope.dataVoArray[i].iTotalPointCount);
                    if (iMaxObjectCount < scope.dataVoArray[i].iTotalPointCount)
                        iMaxObjectCount = scope.dataVoArray[i].iTotalPointCount;
                }
    
                for (var iIndex = 0, iArrayLen = scope.dataVoArray.length; iIndex < iArrayLen; iIndex++) {
                    if (scope.dataVoArray[iIndex].iTotalPointCount < iMaxObjectCount) {
                        if (iIndex == 0) {
                            for (var i = scope.dataVoArray[iIndex].iTotalPointCount, iLen = iMaxObjectCount; i < iLen; i++) {
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[0]);
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[1]);
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[2]);
                                scope.dataVoArray[iIndex].geometry.vertices.push(
                                    new THREE.Vector3(0, 0, 0)
                                );
                            }
                        }
                        else {
                            for (var i = scope.dataVoArray[iIndex].iTotalPointCount, iLen = iMaxObjectCount; i < iLen; i++) {
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[0]);
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[1]);
                                scope.dataVoArray[iIndex].objectPoints.push(scope.dataVoArray[iIndex].objectPoints[2]);
                            }
                        }
                    }
                }
    
                if (params.material == null || params.material == undefined) {
                    console.warn(strLogHead + "[Init] : params.material is not setted; use default material;");
                    var material = new THREE.PointsMaterial({
                        color: 0xffffff,
                        size: 0.2,
                        transparent: true,
                        blending: THREE.AdditiveBlending
                    });
    
                    scope.material = material;
                }
                else
                    scope.material = params.material;
    
                scope.__createPointCloud(scope.dataVoArray[0].geometry, scope.material, function (cp) {
                    onFinished(cp);
                });
            }
        }
    
        this.DoAnimation = function (onFinished) {
            if (this.bIsTransforming)
                return;
    
            scope.iAnimateIndex++;
            if (scope.iAnimateIndex >= scope.iAnimateIndexArray.length)
                scope.iAnimateIndex = 0;
    
            scope.fLerp = 0;
            scope.bIsTransforming = true;
    
            if (onFinished != null && onFinished != undefined)
                scope.onTriggerDoAnimationFinished = onFinished;
        }
    
        this.Tick = function (fps) {
            scope.__doingAnimation(fps);
        }
    
        this.Uninit = function () {
            if (bEnableLog)
                console.log(strLogHead + "[Uninit];");
    
            scope.iAnimateIndex = 0;
            scope.bIsTransforming = false;
            scope.fLerp = 0;
    
            if (scope.dataVoArray != null && scope.dataVoArray != undefined) {
                for (var i = 0, iLen = scope.dataVoArray.length; i < iLen; i++) {
                    if (scope.dataVoArray[i].objectPoints != null && scope.dataVoArray[i].objectPoints != undefined)
                        scope.dataVoArray[i].objectPoints = [];
    
                    if (scope.dataVoArray[i].geometry != null && scope.dataVoArray[i].geometry != undefined)
                        scope.dataVoArray[i].geometry.dispose();
                }
            }
    
            scope.dataVoArray = [];
            scope.iAnimateIndexArray = [];
            if (scope.pointCloud != null && scope.pointCloud != undefined)
                scope.pointCloud.dispose();
    
            if (scope.material != null && scope.material != undefined)
                scope.material.dispose();
    
            scope.pointCloud = null;
            scope.material = null;
        }
    
        //----public functions
    
        //private functions----
        this.__createPointCloud = function (geom, mat, onFinished) {
            if (bEnableLog)
                console.log(strLogHead + "[__createPointCloud];");
    
            if (scope.pointCloud != null && scope.pointCloud != undefined)
                scope.pointCloud.dispose();
    
            scope.pointCloud = new THREE.Points(geom, mat);
            scope.pointCloud.sortParticles = true;
            onFinished(scope.pointCloud);
        }
    
        this.__doingAnimation = function (fps) {
            if (scope.pointCloud == null || scope.pointCloud == undefined || !scope.bIsTransforming)
                return;
    
            var step = scope.dataVoArray[scope.iAnimateIndexArray[scope.iAnimateIndex]].fStep;
    
            if (fps != null && fps != undefined)
                step *= (30 / fps);
            scope.fLerp += step;
    
            var index = 0;
            var x = 0;
            var y = 0;
            var z = 0;
            var positions = scope.pointCloud.geometry.vertices;
            var iLastIndex = scope.iAnimateIndex - 1;
            if (iLastIndex < 0)
                iLastIndex = scope.iAnimateIndexArray.length - 1;
    
            var fSin = Math.sin(scope.fLerp * 3.14);
            var fRandomRange = 2;
            for (var i = 0, iLen = scope.pointCloud.geometry.vertices.length; i < iLen; i++) {
                x = THREE.Math.lerp(scope.dataVoArray[scope.iAnimateIndexArray[iLastIndex]].objectPoints[index], scope.dataVoArray[scope.iAnimateIndexArray[scope.iAnimateIndex]].objectPoints[index], scope.fLerp);
                x += THREE.Math.randFloat(-fRandomRange, fRandomRange) * fSin;
                index++;
    
                y = THREE.Math.lerp(scope.dataVoArray[scope.iAnimateIndexArray[iLastIndex]].objectPoints[index], scope.dataVoArray[scope.iAnimateIndexArray[scope.iAnimateIndex]].objectPoints[index], scope.fLerp);
                y += THREE.Math.randFloat(-fRandomRange, fRandomRange) * fSin;
                index++;
    
                z = THREE.Math.lerp(scope.dataVoArray[scope.iAnimateIndexArray[iLastIndex]].objectPoints[index], scope.dataVoArray[scope.iAnimateIndexArray[scope.iAnimateIndex]].objectPoints[index], scope.fLerp);
                z += THREE.Math.randFloat(-fRandomRange, fRandomRange) * fSin;
                index++;
    
                positions[i] = new THREE.Vector3(x, y, z);
            }
    
            scope.pointCloud.geometry.verticesNeedUpdate = true;
    
            if (scope.fLerp >= 1) {
                if (scope.onTriggerDoAnimationFinished != null && scope.onTriggerDoAnimationFinished != undefined) {
                    scope.onTriggerDoAnimationFinished();
                }
                scope.bIsTransforming = false;
            }
        }
        //----private functions
    }
    //----Class PointCloudMeshAnimator
    var WebAudio = function () {
        var strLogHead = "[WebAudio.js] : ";
        var bEnableLog = true;
        var events = [
            "canplay", "canplaythrough", "durationchange", "emptied", "ended", "error",
            "onloadeddata", "loadedmetadata", "loadstart", "pause", "play", "playing",
            "progress", "ratechange", "readystatechange", "seeked", "seeking", "stalled",
            "suspend", "timeupdate", "volumechange", "waiting"
        ];
        var noop = function () {
        };
    
        this.audio = null;
        this.options = null;
        this._events = null;
        var scope = this;
    
        this._init = function (option) {
            if (bEnableLog)
                console.log(strLogHead + "[_init];");
    
            var i;
            var key;
            option = option || {};
            scope._events = events;
            scope.options = {
                src: "",
                autoPlay: false,
                loop: false,
                duration: 0
            };
            for (i = 0; i < events.length; i++) {
                scope.options["on" + firstLetterUppercase(events[i])] = noop;
            }
            for (key in option) {
                if (option.hasOwnProperty(key)) {
                    scope.options[key] = option[key];
                }
            }
    
            scope.audio = new Audio();
    
            var that = scope;
            var i;
            var inIOS = isIOS();
            var options = scope.options;
            for (i = 0; i < scope._events.length; i++) {
                scope._addEventListener(scope._events[i]);
            }
            if (inIOS) {
                if (options.loop) {
    
                    scope.audio.addEventListener("timeupdate", function (e) {
                        if (_getDuration() - scope.audio.currentTime <= 0.8) {
                            scope.audio.currentTime = 0;
                        }
                    }, false);
                }
                if (options.autoPlay) {
                    document.addEventListener("touchstart", _autoPlay, false);
                }
            } else {
                if (options.loop) {
                    scope.audio.loop = true;
                }
                if (options.autoPlay) {
                    _autoPlay();
                }
            }
    
            function _autoPlay() {
                that.load();
                that.play();
                if (inIOS) {
                    document.removeEventListener("touchstart", _autoPlay, false);
                }
            }
    
            function _getDuration() {
                var duration = that.options.duration;
                var audioDuration = that.audio.duration;
                if (typeof audioDuration === "number" && !isNaN(audioDuration) && isFinite(audioDuration)) {
                    duration = audioDuration;
                }
                return duration;
            }
        };
    
        this.load = function (src) {
            if (bEnableLog)
                console.log(strLogHead + "[load];");
            scope.audio.src = src || scope.options.src;
        };
    
        this.play = function () {
            if (bEnableLog)
                console.log(strLogHead + "[play];");
            scope.audio.play();
        };
    
        this.pause = function () {
            if (bEnableLog)
                console.log(strLogHead + "[pause];");
            scope.audio.pause();
        };
    
        this._addEventListener = function (event) {
            if (bEnableLog)
                console.log(strLogHead + "[_addEventListener];");
            scope.audio.addEventListener(event, function (e) {
                scope.options["on" + firstLetterUppercase(event)].call(scope, e);
            }, false);
        }
    };
    
    function firstLetterUppercase(word) {
        if (typeof word === "string" && word.length) {
            return word[0].toUpperCase() + word.substring(1);
        } else {
            return word;
        }
    }
    
    function isIOS() {
        return /iPad|iPhone|iPod/i.test(navigator.userAgent) && !window.MSStream;
    }
    

      


  • 相关阅读:
    Unity3d-UI插件EZGUI官方视频教程
    安装安卓模拟器和unity3d插件EZGUI
    NGUI的原理机制:深入剖析UIPanel,UIWidget,UIDrawCall底层原理
    分享我的2014年3月unity3d面试题与参考答案
    WP8持续集成之通过命令行跑单元测试
    深入学习HttpClient(一)扩展额外的功能
    Windows Phone实用教程:利用Blend为程序添加设计时数据
    WP架构设计(一)MVVM回顾
    Windows Phone Unit Test 环境搭建
    Caliburn Micro框架快速上手(WP)
  • 原文地址:https://www.cnblogs.com/thingjs/p/10338482.html
Copyright © 2011-2022 走看看