zhouenguang 3 лет назад
Родитель
Сommit
28fdeb6ba0

+ 1 - 1
index.html

@@ -56,7 +56,7 @@
       <script src="./libs/babylonjs.serializers.min.js"></script>
       <script src="./libs/babylon.gui.min.js"></script>
       <script src="./libs/babylon.inspector.bundle.js"></script>
-      <script src="./libs/socket.2.3.js""></script>
+      <script src="./libs/socket.2.3.js"></script>
 
       <script type="module">
         import App from "./modules/index.js";

+ 9 - 0
modules/Charactor.js

@@ -5,6 +5,7 @@ export default class Charactor {
         this.mesh = newMeshes[0]
         this.particleSystem = particleSystems[0]
         this.skeleton = skeletons[0]
+        this.modelData = { newMeshes, particleSystems, skeletons, animationGroups }
 
         // 设置人物动画权重
         this.animation = {}
@@ -34,6 +35,14 @@ export default class Charactor {
         }
     }
 
+    set visible(isVisible) {
+        this.modelData.newMeshes.forEach(mesh => mesh.isVisible = isVisible)
+    }
+
+    get visible() {
+        return this.mesh.isVisible
+    }
+
     updateAniTrans() {
 
         // 实时更新角色模型动画

+ 58 - 55
modules/CharactorManager.js

@@ -1,7 +1,7 @@
 import Charactor from "./Charactor.js";
-import common from "./common.js";
-import data from "./data.js";
-import settings from "./settings.js";
+import common from "./utils/common.js";
+import data from "./utils/data.js";
+import settings from "./utils/settings.js";
 
 export default class CharactorManager {
 
@@ -50,55 +50,56 @@ export default class CharactorManager {
 
         if(pickinfo.pickedPoint) {
 
-            this.charactorWalkTo(pickinfo.pickedPoint)
-
-            // // 在行走之前,首先要把人物矫正到45度的倍数(有视频的8个方向)
-
-            // if(this.charactor.actionType.split("-")[1] == "Walking") 
-            // {
-            //     // 如果是行走时改方向的话,相机保持之前已校正的度数,所以不用再改
-            //     this.charactorWalkTo(pickinfo.pickedPoint)
-            // } 
-            // else {
-
-            //     let cameraAlphaAmend = parseInt(this.app.camera.alpha / (Math.PI / 2)) * (Math.PI / 2)
-            //     let sendData = {
-            //         type: "CameraRotate",
-            //         point: this.charactor.mesh.position,
-            //         dirc: {
-            //             from: this.app.camera.alpha % (Math.PI * 2),
-            //             to: cameraAlphaAmend % (Math.PI * 2)
-            //         }
-            //     }
+            // this.charactorWalkTo(pickinfo.pickedPoint)
+
+            // 在行走之前,首先要把人物矫正到45度的倍数(有视频的8个方向)
+
+            if(this.charactor.actionType.split("-")[1] == "Walking") 
+            {
+                // 如果是行走时改方向的话,相机保持之前已校正的度数,所以不用再改
+                this.charactorWalkTo(pickinfo.pickedPoint)
+            } 
+            else {
+
+                let cameraAlphaAmend = parseInt(this.app.camera.alpha / (Math.PI / 2)) * (Math.PI / 2)
+                let sendData = {
+                    type: "CameraRotate",
+                    point: this.charactor.mesh.position,
+                    dirc: {
+                        from: this.app.camera.alpha % (Math.PI * 2),
+                        to: cameraAlphaAmend % (Math.PI * 2)
+                    }
+                }
+                window.connection.socket.emit("RotateCamera", sendData)
                 
-            //     // todo 发送数据
-            //     // common.postData("", sendData).then(response => {
+                // todo 发送数据
+                // common.postData("", sendData).then(response => {
 
-            //         let video = response[0].video
+                    // let video = response[0].video
 
-            //         this.app.updateHouseVideo(video)
+                    // this.app.updateHouseVideo(video)
 
-            //         let rotateAni = new BABYLON.Animation("rotate", "alpha", this.frameRate, 
-            //             BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE);
+                    // let rotateAni = new BABYLON.Animation("rotate", "alpha", this.frameRate, 
+                    //     BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE);
 
-            //         const rotateFrameNum = this.frameRate * video.duration
-            //         const rotateKeyFrames = [{
-            //             frame: 0,
-            //             value: this.app.camera.alpha
-            //         },{
-            //             frame: rotateFrameNum,
-            //             value: cameraAlphaAmend
-            //         }]; 
+                    // const rotateFrameNum = this.frameRate * video.duration
+                    // const rotateKeyFrames = [{
+                    //     frame: 0,
+                    //     value: this.app.camera.alpha
+                    // },{
+                    //     frame: rotateFrameNum,
+                    //     value: cameraAlphaAmend
+                    // }]; 
 
-            //         rotateAni.setKeys(rotateKeyFrames);
+                    // rotateAni.setKeys(rotateKeyFrames);
 
-            //         scene.beginDirectAnimation(this.app.camera, [rotateAni], 0, rotateFrameNum, false, 1, () => {
-            //             // 旋转完后开始行走
-            //             this.charactorWalkTo(pickinfo.pickedPoint)
-            //         })
+                    // scene.beginDirectAnimation(this.app.camera, [rotateAni], 0, rotateFrameNum, false, 1, () => {
+                    //     // 旋转完后开始行走
+                    //     this.charactorWalkTo(pickinfo.pickedPoint)
+                    // })
 
-            //     // })
-            // }
+                // })
+            }
         }
     }
 
@@ -121,23 +122,25 @@ export default class CharactorManager {
             dirc: this.app.camera.alpha % (Math.PI * 2)
         }
 
+        window.connection.socket.emit("Walk", sendData)
+
         // todo 发送数据
         // common.postData("", sendData).then(response => {
 
-            let path = data.walkPath    // response
-            path.forEach(data => data.point = this.pointsData[data.id].position)
+            // let path = data.walkPath    // response
+            // path.forEach(data => data.point = this.pointsData[data.id].position)
 
-            path = path.map(data => { 
-                return { 
-                    point: new BABYLON.Vector3(data.point.x, 0, data.point.y), 
-                    video: data.video && common.createVideoElement(data.video) 
-                } 
-            })
+            // path = path.map(data => { 
+            //     return { 
+            //         point: new BABYLON.Vector3(data.point.x, 0, data.point.y), 
+            //         video: data.video && common.createVideoElement(data.video) 
+            //     } 
+            // })
 
-            // 行走时锁定camera
-            this.app.lockCamera(true)
+            // // 行走时锁定camera
+            // this.app.lockCamera(true)
 
-            this.charactor.startWalk(path, this)
+            // this.charactor.startWalk(path, this)
 
         // })
 

+ 30 - 20
modules/index.js

@@ -1,7 +1,7 @@
 import CharactorManager from "./CharactorManager.js";
-import common from "./common.js";
-import houseShader from "./houseShader.js";
-import settings from "./settings.js";
+import common from "./utils/common.js";
+import houseShader from "./shaders/houseShader.js";
+import settings from "./utils/settings.js";
 
 export default class App {
 
@@ -16,15 +16,13 @@ export default class App {
         scene.activeCamera.attachControl(scene.canvas, true);
         camera1.inertia = 0
         camera1.minZ = 0
-        camera1.fov = Math.PI / 2
+        camera1.fov = settings.camera.fov
         camera1.fovMode = BABYLON.ArcRotateCamera.FOVMODE_HORIZONTAL_FIXED
         camera1.lowerBetaLimit = Math.PI / 2
         camera1.upperBetaLimit = Math.PI / 2
         camera1.lowerRadiusLimit = settings.camera.distanceFromCharactor;
         camera1.upperRadiusLimit = settings.camera.distanceFromCharactor;
-        camera1.wheelDeltaPercentage = 0.01;
         camera1.angularSensibilityX /= 2;
-        // camera1.targetScreenOffset = new BABYLON.Vector2(0, -1.65)
         this.camera = camera1
         this.lastCameraAlpha = 0
         // camera1.checkCollisions = true;
@@ -46,10 +44,9 @@ export default class App {
         // }
         // console.error(camera1)
 
-        
-        var ray = new BABYLON.Ray(new BABYLON.Vector3(0,0,0), new BABYLON.Vector3(0,0,1), 50);
-        BABYLON.RayHelper.CreateAndShow(ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
-        this.ray = ray
+        // 人物相机射线
+        this.ray = new BABYLON.Ray(new BABYLON.Vector3(0,0,0), new BABYLON.Vector3(0,0,1), 50);
+        BABYLON.RayHelper.CreateAndShow(this.ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
     
         // Lights
         var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, -1, 0), scene);
@@ -80,9 +77,10 @@ export default class App {
             
             self.house = newMeshes
             self.house[0].position = new BABYLON.Vector3(0.6, 2.1, 1.5)
+            // self.house[0].position = new BABYLON.Vector3(-22, 0, 12)
 
             newMeshes.forEach(m => {
-                // m.scaling.scaleInPlace(1.4);
+                // m.scaling.scaleInPlace(100);
                 m._geometry && (m.checkCollisions = true)
 
                 if(m.material) 
@@ -101,7 +99,12 @@ export default class App {
                     // document.getElementById("houseTexture0").loop = "loop"
 
                     shaderMaterial.setTexture("texture_video", videoTexture)
-                    shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(735, settings.video.width, settings.video.height))   // 1100 470 860
+                    // shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(735, settings.video.width, settings.video.height))   // 1100 470 860
+                    shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(
+                        735 * window.innerHeight / settings.video.height, 
+                        settings.video.width * window.innerHeight / settings.video.height, 
+                        window.innerHeight
+                    ))
                     shaderMaterial.setFloat("isYUV", 0)
 
                     m.material = shaderMaterial
@@ -168,18 +171,23 @@ export default class App {
         
         // 实时更新相机target
         let cameraTarget = this.charactorManager.charactor.mesh.position.clone()
-        cameraTarget.y = 1.5
-        this.camera.target = cameraTarget
+        cameraTarget.y = settings.camera.height
+        this.camera.setTarget(cameraTarget)
 
         // 相机碰撞检测
         this.ray.origin = cameraTarget
         this.ray.direction = BABYLON.Vector3.Normalize( this.camera.position.clone().subtract(cameraTarget) )
         let info = this.ray.intersectsMeshes(this.house)[0];
-        const offset = 0.5
-        if(info.distance > settings.camera.distanceFromCharactor + offset) return
+        const offset = 0.6
+        if(!info || info.distance > settings.camera.distanceFromCharactor + offset) return
+        let charactorVisi = this.charactorManager.charactor.visible
         this.camera.lowerRadiusLimit = Math.max( info.distance - offset, 0.1 )
         this.camera.upperRadiusLimit = Math.max( info.distance - offset, 0.1 )
         // console.error(info.pickedPoint, this.camera.position)
+        
+        // 根据相机位置更新人物显隐
+        if(info.distance - offset < 0.25 && charactorVisi) this.charactorManager.charactor.visible = false
+        if(info.distance - offset >= 0.25 && !charactorVisi) this.charactorManager.charactor.visible = true
 
         // let r = this.cameraCollision()
         // this.camera.lowerRadiusLimit = Math.max( r, 0.1 )
@@ -212,10 +220,12 @@ export default class App {
                 }
             }
 
-            setTimeout(() => {
-                // this.lastCameraAlpha = this.camera.alpha
-                this.lockCamera(false)
-            }, 10)
+            window.connection.socket.emit("RotateCamera", sendData)
+
+            // setTimeout(() => {
+            //     // this.lastCameraAlpha = this.camera.alpha
+            //     this.lockCamera(false)
+            // }, 10)
 
             // todo 发送数据
             // common.postData("", sendData).then(response => {

+ 48 - 0
modules/shaders/ScreenTexture.frag

@@ -0,0 +1,48 @@
+precision highp  float;
+
+varying vec3 ModelPos;
+
+uniform float isYUV;  // false: 0, true: 1.0
+uniform sampler2D texture_video;
+
+uniform vec3 focal_width_height;
+
+vec2 SampleTex(vec3 pt3d)
+{
+    return focal_width_height.x / focal_width_height.yz * pt3d.xy / pt3d.z + 0.5;
+}
+
+void main()
+{
+    vec3 color = vec3(0,0,0);
+    float shadow = 1.0;
+    
+    vec2 uv =  SampleTex( normalize(ModelPos) );
+
+    if( isYUV < 0.5 )
+    {
+        color = texture2D(texture_video, uv).rgb;
+    }else{
+        const mat4 YUV2RGB = mat4
+        (
+            1.1643828125, 0, 1.59602734375, -.87078515625,
+            1.1643828125, -.39176171875, -.81296875, .52959375,
+            1.1643828125, 2.017234375, 0, -1.081390625,
+            0, 0, 0, 1
+        );    
+        
+        vec4 result = vec4( 
+            texture2D( texture_video, vec2( uv.x,   uv.y * 0.666666 + 0.333333 ) ).x,
+            texture2D( texture_video, vec2( uv.x * 0.5,        uv.y * 0.333333 ) ).x, 
+            texture2D( texture_video, vec2( 0.5 + uv.x * 0.5,  uv.y * 0.333333 ) ).x,
+            1
+        ) * YUV2RGB;  
+
+        color = clamp(result.rgb, 0.0, 1.0); 
+    }
+    if( uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 )
+    {
+        color = vec3(0,0,0);
+    }
+    gl_FragColor = vec4(shadow * color * 1.0, 1.0); 
+}

+ 17 - 0
modules/shaders/ScreenTexture.vert

@@ -0,0 +1,17 @@
+precision highp float;
+
+varying vec3 ModelPos;
+
+attribute vec2 uv;
+attribute vec3 position;
+
+uniform mat4 view;
+uniform mat4 projection;
+
+uniform mat4 world;
+
+void main()
+{
+    ModelPos = vec3( view * world * vec4(position , 1.0));
+    gl_Position = projection * view * world * vec4(position , 1.0); 
+}

modules/houseShader copy.js → modules/shaders/houseShader copy.js


+ 6 - 7
modules/houseShader.js

@@ -1,15 +1,17 @@
+
 export default {
     
     attributes: ['uv', 'position'],
 
-    uniforms: ['view', 'projection', 'worldViewProjection', 'world', 
+    uniforms: ['view', 'projection', 'world', 
         'isYUV', 'focal_width_height', 'texture_video'],
 
     defines: ["#define SHADOWFULLFLOAT", "#define NUM_BONE_INFLUENCERS 0", "#define NUM_MORPH_INFLUENCERS 0"],
 
     samplers: ['shadowSampler', 'texture_video'],
 
-    vertex: `
+    vertex: 
+    `
 
         precision highp float;
 
@@ -22,14 +24,11 @@ export default {
         uniform mat4 projection;
         
         uniform mat4 world;
-        uniform mat4 worldViewProjection;
 
         void main()
         {
-            #include<instancesVertex>
-        
-            ModelPos = vec3( view * finalWorld * vec4(position , 1.0));
-            gl_Position = projection * view * finalWorld * vec4(position , 1.0); 
+            ModelPos = vec3( view * world * vec4(position , 1.0));
+            gl_Position = projection * view * world * vec4(position , 1.0); 
         }
 
     `,

modules/common.js → modules/utils/common.js


modules/data.js → modules/utils/data.js


modules/settings.js → modules/utils/settings.js


BIN
scenes/house/room02.glb