コード例 #1
0
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page = null)
        {
            // 20140704 no balls shown?
            // broken?
            // view-source:http://www.mrdoob.com/lab/javascript/beachballs/
            //Action Toggle = DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole();


            var origin = new THREE.Vector3(0, 15, 0);
            var isMouseDown = false;



            var renderer = new THREE.WebGLRenderer(
                new
                {
                    antialias = true,
                    alpha = false
                });
            renderer.setClearColor(new THREE.Color(0x101010));

            renderer.domElement.AttachToDocument();



            // scene

            var camera = new THREE.PerspectiveCamera(
                40,
                Native.window.aspect, 1,
                1000
                );

            camera.position.x = -30;
            camera.position.y = 10;
            camera.position.z = 30;
            camera.lookAt(new THREE.Vector3(0, 10, 0));


            #region AtResize
            Action AtResize = delegate
            {
                camera.aspect = (double)Native.window.aspect;
                camera.updateProjectionMatrix();
                renderer.setSize(Native.window.Width, Native.window.Height);
            };
            Native.window.onresize +=
              delegate
              {
                  AtResize();
              };

            AtResize();
            #endregion


            var scene = new THREE.Scene();

            var light = new THREE.HemisphereLight(0xffffff, 0x606060, 1.2);
            light.position.set(-10, 10, 10);
            scene.add(light);

            {
                var geometry = new THREE.CubeGeometry(20, 20, 20);
                var material = new THREE.MeshBasicMaterial(
                    new { wireframe = true, opacity = 0.1, transparent = true });
                var mesh = new THREE.Mesh(geometry, material);
                mesh.position.y = 10;
                scene.add(mesh);
            }

            var intersectionPlane = new THREE.Mesh(new THREE.PlaneGeometry(20, 20, 8, 8));
            intersectionPlane.position.y = 10;
            intersectionPlane.visible = false;
            scene.add(intersectionPlane);

            // geometry

            var ballGeometry = new THREE.Geometry();

            var ballMaterial = new THREE.MeshPhongMaterial(

                new __MeshPhongMaterialDictionary
                {
                    vertexColors = THREE.FaceColors,
                    specular = 0x808080,
                    shininess = 2000
                }
             );

            //

            var colors = new[] {
                    new THREE.Color( 0xe52b30 ),
                    new THREE.Color( 0xe52b30 ),
                    new THREE.Color( 0x2e1b6a ),
                    new THREE.Color( 0xdac461 ),
                    new THREE.Color( 0xf07017 ),
                    new THREE.Color( 0x38b394 ),
                    new THREE.Color( 0xeaf1f7 )
                };

            var amount = colors.Length;

            var geometryTop = new THREE.SphereGeometry(1, 5 * amount, 2, 0, Math.PI * 2.0, 0, 0.30);

            for (var j = 0; j < geometryTop.faces.Length; j++)
            {

                geometryTop.faces[j].color = colors[0];

            }

            THREE.GeometryUtils.merge(ballGeometry, geometryTop);

            var geometryBottom = new THREE.SphereGeometry(1, 5 * amount, 2, 0, Math.PI * 2, Math.PI - 0.30, 0.30);

            for (var j = 0; j < geometryBottom.faces.Length; j++)
            {

                geometryBottom.faces[j].color = colors[0];

            }

            THREE.GeometryUtils.merge(ballGeometry, geometryBottom);

            {
                var sides = amount - 1;
                var size = (Math.PI * 2) / sides;

                for (var i = 0; i < sides; i++)
                {

                    var patch = new THREE.SphereGeometry(1, 5, 10, i * size, size, 0.30, Math.PI - 0.60);

                    for (var j = 0; j < patch.faces.Length; j++)
                    {

                        patch.faces[j].color = colors[i + 1];

                    }

                    THREE.GeometryUtils.merge(ballGeometry, patch);

                }

            }
            // physics

            var world = new CANNON.World();
            world.broadphase = new CANNON.NaiveBroadphase();
            world.gravity.set(0, -15, 0);
            world.solver.iterations = 7;
            world.solver.tolerance = 0.1;

            var groundShape = new CANNON.Plane();
            var groundMaterial = new CANNON.Material();
            var groundBody = new CANNON.RigidBody(0, groundShape, groundMaterial);
            groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2.0);
            world.add(groundBody);

            var planeShapeXmin = new CANNON.Plane();
            var planeXmin = new CANNON.RigidBody(0, planeShapeXmin, groundMaterial);
            planeXmin.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), Math.PI / 2.0);
            planeXmin.position.set(-10, 0, 0);
            world.add(planeXmin);

            var planeShapeXmax = new CANNON.Plane();
            var planeXmax = new CANNON.RigidBody(0, planeShapeXmax, groundMaterial);
            planeXmax.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), -Math.PI / 2.0);
            planeXmax.position.set(10, 0, 0);
            world.add(planeXmax);

            var planeShapeYmin = new CANNON.Plane();
            var planeZmin = new CANNON.RigidBody(0, planeShapeYmin, groundMaterial);
            planeZmin.position.set(0, 0, -10);
            world.add(planeZmin);

            var planeShapeYmax = new CANNON.Plane();
            var planeZmax = new CANNON.RigidBody(0, planeShapeYmax, groundMaterial);
            planeZmax.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), Math.PI);
            planeZmax.position.set(0, 0, 10);
            world.add(planeZmax);

            var ballBodyMaterial = new CANNON.Material();
            world.addContactMaterial(new CANNON.ContactMaterial(groundMaterial, ballBodyMaterial, 0.2, 0.5));
            world.addContactMaterial(new CANNON.ContactMaterial(ballBodyMaterial, ballBodyMaterial, 0.2, 0.8));



            var spheres = new Queue<THREE.Mesh>();
            var bodies = new Queue<CANNON.RigidBody>();

            Func<double> random = new Random().NextDouble;


            #region addBall
            Action<double, double, double> addBall = (x, y, z) =>
            {

                x = Math.Max(-10, Math.Min(10, x));
                y = Math.Max(5, y);
                z = Math.Max(-10, Math.Min(10, z));

                var size = 1.25;

                var sphere = new THREE.Mesh(ballGeometry, ballMaterial);
                sphere.scale.multiplyScalar(size);
                //sphere.useQuaternion = true;
                scene.add(sphere);

                spheres.Enqueue(sphere);

                var sphereShape = new CANNON.Sphere(size);
                var sphereBody = new CANNON.RigidBody(0.1, sphereShape, ballBodyMaterial);
                sphereBody.position.set(x, y, z);

                var q = new
                {
                    a = random() * 3.0,
                    b = random() * 3.0,
                    c = random() * 3.0,
                    d = random() * 3.0
                };
                Console.WriteLine("addBall " + new { x, y, z, q });

                //sphereBody.quaternion.set(q.a, q.b, q.c, q.d);
                world.add(sphereBody);

                bodies.Enqueue(sphereBody);

            };
            #endregion


            for (var i = 0; i < 100; i++)
            {

                addBall(
                   random() * 10 - 5,
                   random() * 20,
                   random() * 10 - 5
                );

            }

            //

            var projector = new THREE.Projector();
            var ray = new THREE.Raycaster();
            var mouse3D = new THREE.Vector3();

            Native.Document.body.ontouchstart +=
               e =>
               {
                   e.preventDefault();
                   isMouseDown = true;
               };


            Native.Document.body.ontouchmove +=
               e =>
               {
                   e.preventDefault();
               };

            Native.Document.body.ontouchend +=
            e =>
            {
                e.preventDefault();
                isMouseDown = false;
            };

            #region onmousemove
            Native.document.body.onmousedown +=
                e =>
                {
                    e.preventDefault();
                    isMouseDown = true;
                };
            Native.document.body.onmouseup +=
                 e =>
                 {
                     e.preventDefault();
                     isMouseDown = false;



                     if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                     {
                         if (Native.Document.pointerLockElement == Native.Document.body)
                         {
                             // cant requestFullscreen while pointerLockElement
                             Console.WriteLine("exitPointerLock");
                             Native.Document.exitPointerLock();
                             Native.Document.exitFullscreen();
                             return;
                         }

                         Console.WriteLine("requestFullscreen");
                         Native.Document.body.requestFullscreen();
                         Native.Document.body.requestPointerLock();
                         return;
                     }
                 };
            Native.document.body.onmousemove +=
               e =>
               {

                   mouse3D.set(
                       ((double)e.CursorX / (double)Native.window.Width) * 2 - 1,
                       -((double)e.CursorY / (double)Native.window.Height) * 2 + 1,
                       0.5
                   );

                   projector.unprojectVector(mouse3D, camera);

                   ray.set(camera.position, mouse3D.sub(camera.position).normalize());

                   var intersects = ray.intersectObject(intersectionPlane);

                   if (intersects.Length > 0)
                   {

                       origin.copy(intersects[0].point);

                   }
               };
            #endregion








            #region removeBall
            Action removeBall = delegate
            {

                scene.remove(spheres.Dequeue());
                world.remove(bodies.Dequeue());

            };
            #endregion




            var sw0 = Stopwatch.StartNew();
            var sw = Stopwatch.StartNew();
            //var time = Native.window.performance.now();
            //var lastTime = Native.window.performance.now();

            #region animate
            Action render =
                delegate
                {

                    var delta = sw.ElapsedMilliseconds;
                    sw.Restart();

                    //time = Native.window.performance.now();

                    camera.position.x = -Math.Cos(sw.ElapsedMilliseconds * 0.0001) * 40;
                    camera.position.z = Math.Sin(sw.ElapsedMilliseconds * 0.0001) * 40;
                    camera.lookAt(new THREE.Vector3(0, 10, 0));

                    intersectionPlane.lookAt(camera.position);

                    world.step(delta * 0.001);
                    //lastTime = time;

                    for (var i = 0; i < spheres.Count; i++)
                    {

                        var sphere = spheres.ElementAt(i);
                        var body = bodies.ElementAt(i);

                        sphere.position.copy(body.position);
                        sphere.quaternion.copy(body.quaternion);

                    }

                    renderer.render(scene, camera);

                };



            Native.window.onframe += delegate
            {


                if (isMouseDown)
                {

                    if (spheres.Count > 200)
                    {

                        removeBall();

                    }

                    addBall(
                        origin.x + (random() * 4.0 - 2),
                        origin.y + (random() * 4.0 - 2),
                        origin.z + (random() * 4.0 - 2)
                    );

                }

                render();

            };

            #endregion


        }
コード例 #2
0
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20140815/webglcannonphysicsengine

        // inspired by http://granular.cs.umu.se/cannon.js/examples/threejs_fps.html


        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page = null)
        {
            //Uncaught Error: ERROR: Quaternion's .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.  Please update your code. 

            // WEBGL11095: INVALID_OPERATION: clearStencil: Method not currently supported
            // IE11 does not work yet

            //DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole();

            //            DEPRECATED: Quaternion's .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead. Three.js:913
            //Uncaught TypeError: Object [object Object] has no method 'subSelf' 
            // { REVISION: '57' };

            var boxes = new List<CANNON.RigidBody>();
            var boxMeshes = new List<THREE.Mesh>();

            var balls = new List<CANNON.RigidBody>();
            var ballMeshes = new List<THREE.Mesh>();



            Func<long> Date_now = () => (long)new IFunction("return Date.now();").apply(null);

            var time = Date_now();







            #region initCannon
            //    // Setup our world
            var world = new CANNON.World();

            world.quatNormalizeSkip = 0;
            world.quatNormalizeFast = false;
            //world.solver.setSpookParams(300, 10);
            world.solver.iterations = 5;
            world.gravity.set(0, -20, 0);
            world.broadphase = new CANNON.NaiveBroadphase();

            //    // Create a slippery material (friction coefficient = 0.0)
            var physicsMaterial = new CANNON.Material("slipperyMaterial");


            var physicsContactMaterial = new CANNON.ContactMaterial(
                physicsMaterial,
                physicsMaterial,
                0.0, // friction coefficient
                0.3  // restitution
            );

            //    // We must add the contact materials to the world
            world.addContactMaterial(physicsContactMaterial);

            var controls_sphereShape = default(CANNON.Sphere);
            var controls_sphereBody = default(CANNON.RigidBody);

            {    // Create a sphere
                var mass = 5;
                var radius = 1.3;
                var sphereShape = new CANNON.Sphere(radius);
                var sphereBody = new CANNON.RigidBody(mass, sphereShape, physicsMaterial);
                controls_sphereShape = sphereShape;
                controls_sphereBody = sphereBody;
                sphereBody.position.set(0, 5, 0);
                sphereBody.linearDamping = 0.05;
                world.add(sphereBody);

                //    // Create a plane
                var groundShape = new CANNON.Plane();
                var groundBody = new CANNON.RigidBody(0, groundShape, physicsMaterial);
                groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
                world.add(groundBody);
            }
            #endregion

            #region init

            var camera = new THREE.PerspectiveCamera(75, Native.window.aspect, 0.1, 1000);

            var scene = new THREE.Scene();
            scene.fog = new THREE.Fog(0x000000, 0, 500);

            var ambient = new THREE.AmbientLight(0x111111);
            scene.add(ambient);

            var light = new THREE.SpotLight(0xffffff, 1.0);
            light.position.set(10, 30, 20);
            light.target.position.set(0, 0, 0);
            //    if(true){
            light.castShadow = true;

            light.shadowCameraNear = 20;
            light.shadowCameraFar = 50;//camera.far;
            light.shadowCameraFov = 40;

            light.shadowMapBias = 0.1;
            light.shadowMapDarkness = 0.7;
            light.shadowMapWidth = 2 * 512;
            light.shadowMapHeight = 2 * 512;

            //        //light.shadowCameraVisible = true;
            //    }
            scene.add(light);



            var controls = new PointerLockControls(camera, controls_sphereBody);
            scene.add(controls.getObject());

            //    // floor
            var geometry = new THREE.PlaneGeometry(300, 300, 50, 50);
            geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));

            var material = new THREE.MeshLambertMaterial(new { color = 0xdddddd });

            //Native.Window.




            // THREE.Design.THREE.ColorUtils.adjustHSV(material.color, 0, 0, 0.9);

            //  Replaced ColorUtils.adjustHSV() with Color's .offsetHSL(). 
            //new IFunction("material", "THREE.ColorUtils.offsetHSL( material.color, 0, 0, 0.9 );").apply(null, material);

            //    

            var mesh = new THREE.Mesh(geometry, material)
            {
                castShadow = true,
                receiveShadow = true
            };

            scene.add(mesh);

            var renderer = new THREE.WebGLRenderer(new object());
            renderer.shadowMapEnabled = true;
            renderer.shadowMapSoft = true;
            //renderer.setSize(Native.Window.Width, Native.Window.Height);
            //renderer.setClearColor(scene.fog.color, 1);

            renderer.domElement.style.backgroundColor = JSColor.Black;
            renderer.domElement.AttachToDocument();



            #region onresize
            Action AtResize = delegate
            {
                camera.aspect = Native.window.aspect;
                camera.updateProjectionMatrix();
                renderer.setSize(Native.window.Width, Native.window.Height);
            };
            Native.window.onresize +=
              delegate
              {
                  AtResize();
              };

            AtResize();
            #endregion


            var r = new Random();
            Func<f> Math_random = () => r.NextFloat();

            #region Add boxes
            {    // 

                for (var i = 0; i < 32; i++)
                {
                    var boxsize = Math_random() * 0.5;

                    var halfExtents = new CANNON.Vec3(boxsize, boxsize, boxsize);

                    var boxShape = new CANNON.Box(halfExtents);
                    var boxGeometry = new THREE.CubeGeometry(halfExtents.x * 2, halfExtents.y * 2, halfExtents.z * 2);

                    var x = (Math_random() - 0.5) * 20;
                    var y = 1 + (Math_random() - 0.5) * 1;
                    var z = (Math_random() - 0.5) * 20;
                    var boxBody = new CANNON.RigidBody(5, boxShape);
                    var boxMesh = new THREE.Mesh(boxGeometry, material);
                    world.add(boxBody);
                    scene.add(boxMesh);
                    boxBody.position.set(x, y, z);
                    boxMesh.position.set(x, y, z);
                    boxMesh.castShadow = true;
                    boxMesh.receiveShadow = true;
                    //boxMesh.useQuaternion = true;

                    boxes.Add(boxBody);
                    boxMeshes.Add(boxMesh);
                }
            }
            #endregion

            #region Add linked boxes
            {    // 
                var size = 0.5;
                var he = new CANNON.Vec3(size, size, size * 0.1);
                var boxShape = new CANNON.Box(he);
                var mass = 0.0;
                var space = 0.1 * size;
                var N = 5;
                var last = default(CANNON.RigidBody);

                var boxGeometry = new THREE.CubeGeometry(he.x * 2, he.y * 2, he.z * 2);

                for (var i = 0; i < N; i++)
                {
                    var boxbody = new CANNON.RigidBody(mass, boxShape);
                    var boxMesh = new THREE.Mesh(boxGeometry, material);
                    boxbody.position.set(5, (N - i) * (size * 2 + 2 * space) + size * 2 + space, 0);
                    boxbody.linearDamping = 0.01;
                    boxbody.angularDamping = 0.01;
                    //boxMesh.useQuaternion = true;
                    boxMesh.castShadow = true;
                    boxMesh.receiveShadow = true;

                    world.add(boxbody);
                    scene.add(boxMesh);

                    boxes.Add(boxbody);
                    boxMeshes.Add(boxMesh);

                    if (i != 0)
                    {
                        // Connect this body to the last one
                        var c1 = new CANNON.PointToPointConstraint(boxbody, new CANNON.Vec3(-size, size + space, 0), last, new CANNON.Vec3(-size, -size - space, 0));
                        var c2 = new CANNON.PointToPointConstraint(boxbody, new CANNON.Vec3(size, size + space, 0), last, new CANNON.Vec3(size, -size - space, 0));

                        world.addConstraint(c1);
                        world.addConstraint(c2);
                    }
                    else
                    {
                        mass = 0.3;
                    }
                    last = boxbody;
                }
            }
            #endregion

            #endregion


            var dt = 1.0 / 60;
            controls.enabled = true;

            // vr and tilt shift?

            Native.window.onframe += delegate
            {

                if (controls.enabled)
                {
                    // how big of a world can we hold?
                    // async ?
                    world.step(dt);

                    // Update ball positions
                    for (var i = 0; i < balls.Count; i++)
                    {
                        balls[i].position.copy(ballMeshes[i].position);
                        balls[i].quaternion.copy(ballMeshes[i].quaternion);
                    }

                    // Update box positions
                    for (var i = 0; i < boxes.Count; i++)
                    {
                        boxes[i].position.copy(boxMeshes[i].position);
                        boxes[i].quaternion.copy(boxMeshes[i].quaternion);
                    }
                }

                controls.update(Date_now() - time);
                renderer.render(scene, camera);
                time = Date_now();


            };



            #region havePointerLock

            renderer.domElement.onclick +=
                delegate
                {
                    renderer.domElement.requestPointerLock();
                };


            #endregion



            #region onmousedown
            renderer.domElement.onmousedown +=
                e =>
                {
                    if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                    {
                        if (Native.document.pointerLockElement == Native.document.body)
                        {
                            // cant requestFullscreen while pointerLockElement
                            Console.WriteLine("exitPointerLock");
                            Native.document.exitPointerLock();
                            Native.document.exitFullscreen();
                            return;
                        }

                        Console.WriteLine("requestFullscreen");
                        renderer.domElement.requestFullscreen();
                        renderer.domElement.requestPointerLock();
                        return;
                    }

                    var ballradius = 0.1 + Math_random() * 0.9;

                    var ballShape = new CANNON.Sphere(ballradius);
                    var ballGeometry = new THREE.SphereGeometry(ballShape.radius, 32, 32);
                    var shootDirection = new THREE.Vector3();
                    var shootVelo = 15;
                    var projector = new THREE.Projector();

                    Action<THREE.Vector3> getShootDir = (targetVec) =>
                    {
                        var vector = targetVec;
                        targetVec.set(0, 0, 1);
                        projector.unprojectVector(vector, camera);
                        var ray = new THREE.Ray( (THREE.Vector3)(object)controls_sphereBody.position,
                            vector
                            //.subSelf(controls_sphereBody.position)
                            .normalize()

                            );
                        targetVec.x = ray.direction.x;
                        targetVec.y = ray.direction.y;
                        targetVec.z = ray.direction.z;
                    };


                    var x = controls_sphereBody.position.x;
                    var y = controls_sphereBody.position.y;
                    var z = controls_sphereBody.position.z;

                    // could we attach physics via binding list?
                    var ballBody = new CANNON.RigidBody(1, ballShape);
                    var ballMesh = new THREE.Mesh(ballGeometry, material);
                    world.add(ballBody);
                    scene.add(ballMesh);
                    ballMesh.castShadow = true;
                    ballMesh.receiveShadow = true;
                    balls.Add(ballBody);
                    ballMeshes.Add(ballMesh);
                    getShootDir(shootDirection);
                    ballBody.velocity.set(shootDirection.x * shootVelo,
                                            shootDirection.y * shootVelo,
                                            shootDirection.z * shootVelo);

                    //        // Move the ball outside the player sphere
                    x += shootDirection.x * (controls_sphereShape.radius + ballShape.radius);
                    y += shootDirection.y * (controls_sphereShape.radius + ballShape.radius);
                    z += shootDirection.z * (controls_sphereShape.radius + ballShape.radius);
                    ballBody.position.set(x, y, z);
                    ballMesh.position.set(x, y, z);
                    //ballMesh.useQuaternion = true;
                };
            #endregion



            //var ze = new ZeProperties();

            //ze.Show();

            //ze.Left = 0;

            //ze.Add(() => renderer);
            //ze.Add(() => controls);
            //ze.Add(() => scene);
        }
コード例 #3
0
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            // http://blog.cuartodejuegos.es/wp-content/uploads/2011/06/Story-cubes-caras.jpg
            // http://css-eblog.com/3d/box.html

            var w = Native.window.Width;
            var h = Native.window.Height;

            //      var world, ground, 
            var timeStep = 1 / 60.0;

            //diceRigid, dice,
            //camera, scene, renderer, floorObj,
            //startDiceNum = 3,
            var cubeSize = 3.0;

            #region Cannonの世界を生成
            var world = new CANNON.World();

            //重力を設定
            world.gravity.set(0, -90.82, 0);
            world.broadphase = new CANNON.NaiveBroadphase();
            world.solver.iterations = 10;
            world.solver.tolerance = 0.001;

            //地面用にPlaneを生成
            var plane = new CANNON.Plane();

            //Planeの剛体を質量0で生成する
            var ground = new CANNON.RigidBody(0, plane);

            //X軸に90度(つまり地面)に回転
            ground.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
            ground.position.set(
                50, 0, 50);

            world.add(ground);
            #endregion


            #region initThree() {


            //var camera = new THREE.OrthographicCamera(-w / 2, w / 2, h / 2, -h / 2, 1, 1000);
            var camera = new THREE.PerspectiveCamera(60, w / (double)h, 0.1, 1000);


            camera.lookAt(new THREE.Vector3(0, 0, 0));

            var scene = new THREE.Scene();
            var renderer = new THREE.CSS3DRenderer();
            renderer.setSize(w, h);

            var textureSize = 800;
            var floorEle = new IHTMLDiv();
            //floorEle.style.width = textureSize + "px";
            //floorEle.style.height = textureSize + "px";

            floorEle.style.width = 100 + "px";
            floorEle.style.height = 100 + "px";

            new WebGLDiceByEBLOG.HTML.Images.FromAssets.background().ToBackground(floorEle.style, true);

            //floorEle.style.background = 'url(http://jsrun.it/assets/d/x/0/w/dx0wl.png) left top repeat';
            //floorEle.style.backgroundSize = textureSize / 20 + "px " + textureSize / 20 + "px";
            (floorEle.style as dynamic).backgroundSize = textureSize / 20 + "px " + textureSize / 20 + "px";

            var floorObj = new THREE.CSS3DObject(floorEle);
            //floorObj.position.fromArray(new double[] { 100, 0, 0 });
            //floorObj.rotation.fromArray(new double[] { Math.PI / 2.0, 0, 0 });
            scene.add(floorObj);

            scene.add(camera);

            renderer.domElement.AttachToDocument();

            renderer.render(scene, camera);
            #endregion }



            #region createDice
            Func<xdice> createDice = delegate
            {


                Console.WriteLine("before array");


                //t = new Array(3);
                //p.rotation = t;

                var zero = 0.0;


                #region boxInfo
                var boxInfo = new[] 
                {
                         new xdiceface {
                        img = (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num4(),
                        position= new double [] { 0, 0, -cubeSize },

                        // jsc, please allow 
                        rotation= new double [] { 0, 0, zero }
                    },


                    new  xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num2(),
                        position = new double [] { -cubeSize, 0, 0 },
                        rotation =  new double [] { 0, Math.PI / 2, 0 }
                    },
                    new xdiceface{
                        img = (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num5(),
                        position = new double [] { cubeSize, 0, 0 },
                        rotation= new double [] { 0, -Math.PI / 2, 0 }
                    },
                    new xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num1(),
                        position= new double [] { 0,  cubeSize, 0 },
                        rotation= new double [] { Math.PI / 2, 0, Math.PI }
                    },
                    new xdiceface {
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num6(),
                        position= new double [] { 0, -cubeSize, 0 },
                        rotation= new double [] { - Math.PI / 2, 0, Math.PI }
                    },
                    new xdiceface{
                        img= (IHTMLImage)new WebGLDiceByEBLOG.HTML.Images.FromAssets.num3(),
                        position= new double [] { 0, 0,  cubeSize },
                        rotation= new double [] { 0, Math.PI, 0 }
                    },
               
                };
                #endregion
                Console.WriteLine("after array");

                //for three.js
                //var el, dice,
                //    info, img, face;

                var el = new IHTMLDiv();
                el.style.width = cubeSize * 2 + "px";
                el.style.height = cubeSize * 2 + "px";
                var dice = new THREE.CSS3DObject(el);

                for (var j = 0; j < boxInfo.Length; j++)
                {
                    Console.WriteLine("after array " + new { j });

                    var info = boxInfo[j];

                    info.img.style.SetSize(
                        (int)(cubeSize * 2),
                        (int)(cubeSize * 2)
                    );


                    var face = new THREE.CSS3DObject(info.img);

                    face.position.fromArray(info.position);
                    face.rotation.fromArray(info.rotation);
                    dice.add(face);
                }

                //Create physics.
                var mass = 1;
                var box = new CANNON.Box(new CANNON.Vec3(cubeSize, cubeSize, cubeSize));
                var body = new CANNON.RigidBody(mass, box);

                //body.position.set(x, y, z);
                //body.velocity.set(0, 0, Math.random() * -50 - 30);

                //body.angularVelocity.set(10, 10, 10);
                //body.angularDamping = 0.001;

                return new xdice
                {
                    dice = dice,
                    rigid = body
                };
            };
            #endregion


            //world.allowSleep = true;
            var stopped = false;

            Func<double> random = new Random().NextDouble;

            #region initAnimation
            Action<xdice> initAnimation = y =>
            {
                var position = new
                {
                    x = 5 + random() * 50.0,
                    y = 5 + random() * 50.0,
                    z = 5 + random() * 5.0,
                };

                Console.WriteLine(new { position });
                y.rigid.position.set(position.x, position.y, position.z);

                y.rigid.velocity.set(
                    random() * 20 + 0,
                    random() * 20 + 10,
                    random() * 20 + 10
                    );


                y.rigid.angularVelocity.set(10, 10, 10);
                y.rigid.angularDamping = 0.001;
            };
            #endregion

            //create a dice.

            var AllDice = new List<xdice>();

            for (int i = 0; i < 9; i++)
            {

                var y = createDice();

                initAnimation(y);

                scene.add(y.dice);
                world.add(y.rigid);

                AllDice.Add(y);

            }





            var target = new THREE.Vector3();

            var lon = 50.0;
            var lat = -72.0;





            var drag = false;

            #region onframe
            Native.window.onframe +=
                delegate
                {
                    if (Native.document.pointerLockElement == Native.document.body)
                        lon += 0.00;
                    else
                        lon += 0.01;

                    lat = Math.Max(-85, Math.Min(85, lat));

                    Native.document.title = new { lon = (int)lon, lat = (int)lat }.ToString();


                    var phi = THREE.Math.degToRad(90.0 - lat);
                    var theta = THREE.Math.degToRad(lon);

                    target.x = Math.Sin(phi) * Math.Cos(theta);
                    target.y = Math.Cos(phi);
                    target.z = Math.Sin(phi) * Math.Sin(theta);

                    //XInteractiveInt32Form.ToInteractiveInt32Form(
                    camera.position.set(
                        x: 0,
                        y: 50.ToInteractiveInt32Form(),
                        z: 0
                   );

                    #region updatePhysics();
                    //物理エンジンの時間を進める
                    world.step(timeStep);

                    //物理エンジンで計算されたbody(RigidBody)の位置をThree.jsのMeshにコピー
                    AllDice.WithEach(
                        y =>
                        {
                            y.rigid.position.copy(y.dice.position);
                            y.rigid.quaternion.copy(y.dice.quaternion);

                            //y.rigid.position.copy(camera.position);
                        }
                    );

                    if (!drag)
                    {
                        camera.lookAt(
                            new THREE.Vector3(
                                AllDice.Average(i => i.rigid.position.x),
                                AllDice.Average(i => i.rigid.position.y),
                                AllDice.Average(i => i.rigid.position.z)
                            )
                        );



                    }
                    else
                    {
                        camera.lookAt(
                            new THREE.Vector3(
                                target.x + camera.position.x,
                                target.y + camera.position.y,
                                target.z + camera.position.z
                            )
                        );
                    }

                    ground.position.copy(floorObj.position);
                    ground.quaternion.copy(floorObj.quaternion);
                    #endregion

                    renderer.render(scene, camera);
                };
            #endregion




            #region sleepy
            AllDice.Last().With(
                x =>
                {

                    x.rigid.addEventListener("sleepy",

                        IFunction.OfDelegate(
                            new Action(
                                delegate
                                {

                                    var px = new THREE.Vector4(1, 0, 0, 0);
                                    var nx = new THREE.Vector4(-1, 0, 0, 0);
                                    var py = new THREE.Vector4(0, 1, 0, 0);
                                    var ny = new THREE.Vector4(0, -1, 0, 0);
                                    var pz = new THREE.Vector4(0, 0, 1, 0);
                                    var nz = new THREE.Vector4(0, 0, -1, 0);
                                    var UP = 0.99;
                                    //tmp;

                                    #region showNum
                                    Action<int> showNum = num =>
                                    {
                                        new { num }.ToString().ToDocumentTitle();
                                    };

                                    if (px.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(5);
                                    }
                                    else if (nx.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(2);
                                    }
                                    else if (py.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(1);
                                    }
                                    else if (ny.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(6);
                                    }
                                    else if (pz.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(3);
                                    }
                                    else if (nz.applyMatrix4(x.dice.matrixWorld).y > UP)
                                    {
                                        showNum(4);
                                    }
                                    #endregion

                                    stopped = true;
                                }
                            )
                        )
                    );
                }
            );

            #endregion

            #region onresize
            Action AtResize = delegate
            {
                camera.aspect = Native.window.Width / Native.window.Height;
                camera.updateProjectionMatrix();
                renderer.setSize(Native.window.Width, Native.window.Height);
            };
            Native.window.onresize +=
              delegate
              {
                  AtResize();
              };
            #endregion


            #region onclick
            var button = new IHTMLDiv();

            button.style.position = IStyle.PositionEnum.absolute;
            button.style.left = "0px";
            button.style.right = "0px";
            button.style.bottom = "0px";
            button.style.height = "3em";
            button.style.backgroundColor = "rgba(0,0,0,0.5)";

            button.AttachToDocument();



            button.onmousedown +=
                e =>
                {
                    e.stopPropagation();
                };

            button.ontouchstart +=
                e =>
                {
                    e.stopPropagation();
                };

            button.ontouchmove +=
                 e =>
                 {
                     e.stopPropagation();
                 };

            button.onclick +=
                delegate
                {
                    stopped = false;

                    AllDice.WithEach(
                       y =>
                       {
                           initAnimation(y);
                       }
                    );

                };
            #endregion

            #region ontouchmove
            var touchX = 0;
            var touchY = 0;

            Native.document.body.ontouchend +=
               e =>
               {
                   drag = false;
               };


            Native.document.body.ontouchstart +=
                e =>
                {
                    drag = true;
                    e.preventDefault();

                    var touch = e.touches[0];

                    touchX = touch.screenX;
                    touchY = touch.screenY;

                };


            Native.document.body.ontouchmove +=
              e =>
              {
                  e.preventDefault();

                  var touch = e.touches[0];

                  lon -= (touch.screenX - touchX) * 0.1;
                  lat += (touch.screenY - touchY) * 0.1;

                  touchX = touch.screenX;
                  touchY = touch.screenY;

              };
            #endregion






            #region camera rotation
            renderer.domElement.onmousemove +=
                e =>
                {
                    e.preventDefault();

                    if (Native.document.pointerLockElement == renderer.domElement)
                    {
                        drag = true;
                        lon += e.movementX * 0.1;
                        lat -= e.movementY * 0.1;

                        //Console.WriteLine(new { lon, lat, e.movementX, e.movementY });
                    }
                };


            renderer.domElement.onmouseup +=
              e =>
              {
                  drag = Native.document.pointerLockElement != null;
                  e.preventDefault();
              };

            renderer.domElement.onmousedown +=
                e =>
                {
                    //e.CaptureMouse();

                    drag = true;
                    e.preventDefault();
                    renderer.domElement.requestPointerLock();

                };


            renderer.domElement.ondblclick +=
                e =>
                {
                    e.preventDefault();

                    Console.WriteLine("requestPointerLock");
                };

            #endregion






        }
コード例 #4
0
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20140815/webglcannonphysicsengine

        // inspired by http://granular.cs.umu.se/cannon.js/examples/threejs_fps.html


        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page = null)
        {
            //Uncaught Error: ERROR: Quaternion's .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.  Please update your code.

            // WEBGL11095: INVALID_OPERATION: clearStencil: Method not currently supported
            // IE11 does not work yet

            //DiagnosticsConsole.ApplicationContent.BindKeyboardToDiagnosticsConsole();

            //            DEPRECATED: Quaternion's .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead. Three.js:913
            //Uncaught TypeError: Object [object Object] has no method 'subSelf'
            // { REVISION: '57' };

            var boxes     = new List <CANNON.RigidBody>();
            var boxMeshes = new List <THREE.Mesh>();

            var balls      = new List <CANNON.RigidBody>();
            var ballMeshes = new List <THREE.Mesh>();



            Func <long> Date_now = () => (long)new IFunction("return Date.now();").apply(null);

            var time = Date_now();



            #region initCannon
            //    // Setup our world
            var world = new CANNON.World();

            world.quatNormalizeSkip = 0;
            world.quatNormalizeFast = false;
            //world.solver.setSpookParams(300, 10);
            world.solver.iterations = 5;
            world.gravity.set(0, -20, 0);
            world.broadphase = new CANNON.NaiveBroadphase();

            //    // Create a slippery material (friction coefficient = 0.0)
            var physicsMaterial = new CANNON.Material("slipperyMaterial");


            var physicsContactMaterial = new CANNON.ContactMaterial(
                physicsMaterial,
                physicsMaterial,
                0.0, // friction coefficient
                0.3  // restitution
                );

            //    // We must add the contact materials to the world
            world.addContactMaterial(physicsContactMaterial);

            var controls_sphereShape = default(CANNON.Sphere);
            var controls_sphereBody  = default(CANNON.RigidBody);

            {    // Create a sphere
                var mass        = 5;
                var radius      = 1.3;
                var sphereShape = new CANNON.Sphere(radius);
                var sphereBody  = new CANNON.RigidBody(mass, sphereShape, physicsMaterial);
                controls_sphereShape = sphereShape;
                controls_sphereBody  = sphereBody;
                sphereBody.position.set(0, 5, 0);
                sphereBody.linearDamping = 0.05;
                world.add(sphereBody);

                //    // Create a plane
                var groundShape = new CANNON.Plane();
                var groundBody  = new CANNON.RigidBody(0, groundShape, physicsMaterial);
                groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
                world.add(groundBody);
            }
            #endregion

            #region init

            var camera = new THREE.PerspectiveCamera(75, Native.window.aspect, 0.1, 1000);

            var scene = new THREE.Scene();
            scene.fog = new THREE.Fog(0x000000, 0, 500);

            var ambient = new THREE.AmbientLight(0x111111);
            scene.add(ambient);

            var light = new THREE.SpotLight(0xffffff, 1.0);
            light.position.set(10, 30, 20);
            light.target.position.set(0, 0, 0);
            //    if(true){
            light.castShadow = true;

            light.shadowCameraNear = 20;
            light.shadowCameraFar  = 50;//camera.far;
            light.shadowCameraFov  = 40;

            light.shadowMapBias     = 0.1;
            light.shadowMapDarkness = 0.7;
            light.shadowMapWidth    = 2 * 512;
            light.shadowMapHeight   = 2 * 512;

            //        //light.shadowCameraVisible = true;
            //    }
            scene.add(light);



            var controls = new PointerLockControls(camera, controls_sphereBody);
            scene.add(controls.getObject());

            //    // floor
            var geometry = new THREE.PlaneGeometry(300, 300, 50, 50);
            geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));

            var material = new THREE.MeshLambertMaterial(new { color = 0xdddddd });

            //Native.Window.



            // THREE.Design.THREE.ColorUtils.adjustHSV(material.color, 0, 0, 0.9);

            //  Replaced ColorUtils.adjustHSV() with Color's .offsetHSL().
            //new IFunction("material", "THREE.ColorUtils.offsetHSL( material.color, 0, 0, 0.9 );").apply(null, material);

            //

            var mesh = new THREE.Mesh(geometry, material)
            {
                castShadow    = true,
                receiveShadow = true
            };

            scene.add(mesh);

            var renderer = new THREE.WebGLRenderer(new object());
            renderer.shadowMapEnabled = true;
            renderer.shadowMapSoft    = true;
            //renderer.setSize(Native.Window.Width, Native.Window.Height);
            //renderer.setClearColor(scene.fog.color, 1);

            renderer.domElement.style.backgroundColor = JSColor.Black;
            renderer.domElement.AttachToDocument();



            #region onresize
            Action AtResize = delegate
            {
                camera.aspect = Native.window.aspect;
                camera.updateProjectionMatrix();
                renderer.setSize(Native.window.Width, Native.window.Height);
            };
            Native.window.onresize +=
                delegate
            {
                AtResize();
            };

            AtResize();
            #endregion


            var      r           = new Random();
            Func <f> Math_random = () => r.NextFloat();

            #region Add boxes
            {    //
                for (var i = 0; i < 32; i++)
                {
                    var boxsize = Math_random() * 0.5;

                    var halfExtents = new CANNON.Vec3(boxsize, boxsize, boxsize);

                    var boxShape    = new CANNON.Box(halfExtents);
                    var boxGeometry = new THREE.CubeGeometry(halfExtents.x * 2, halfExtents.y * 2, halfExtents.z * 2);

                    var x       = (Math_random() - 0.5) * 20;
                    var y       = 1 + (Math_random() - 0.5) * 1;
                    var z       = (Math_random() - 0.5) * 20;
                    var boxBody = new CANNON.RigidBody(5, boxShape);
                    var boxMesh = new THREE.Mesh(boxGeometry, material);
                    world.add(boxBody);
                    scene.add(boxMesh);
                    boxBody.position.set(x, y, z);
                    boxMesh.position.set(x, y, z);
                    boxMesh.castShadow    = true;
                    boxMesh.receiveShadow = true;
                    //boxMesh.useQuaternion = true;

                    boxes.Add(boxBody);
                    boxMeshes.Add(boxMesh);
                }
            }
            #endregion

            #region Add linked boxes
            {    //
                var size     = 0.5;
                var he       = new CANNON.Vec3(size, size, size * 0.1);
                var boxShape = new CANNON.Box(he);
                var mass     = 0.0;
                var space    = 0.1 * size;
                var N        = 5;
                var last     = default(CANNON.RigidBody);

                var boxGeometry = new THREE.CubeGeometry(he.x * 2, he.y * 2, he.z * 2);

                for (var i = 0; i < N; i++)
                {
                    var boxbody = new CANNON.RigidBody(mass, boxShape);
                    var boxMesh = new THREE.Mesh(boxGeometry, material);
                    boxbody.position.set(5, (N - i) * (size * 2 + 2 * space) + size * 2 + space, 0);
                    boxbody.linearDamping  = 0.01;
                    boxbody.angularDamping = 0.01;
                    //boxMesh.useQuaternion = true;
                    boxMesh.castShadow    = true;
                    boxMesh.receiveShadow = true;

                    world.add(boxbody);
                    scene.add(boxMesh);

                    boxes.Add(boxbody);
                    boxMeshes.Add(boxMesh);

                    if (i != 0)
                    {
                        // Connect this body to the last one
                        var c1 = new CANNON.PointToPointConstraint(boxbody, new CANNON.Vec3(-size, size + space, 0), last, new CANNON.Vec3(-size, -size - space, 0));
                        var c2 = new CANNON.PointToPointConstraint(boxbody, new CANNON.Vec3(size, size + space, 0), last, new CANNON.Vec3(size, -size - space, 0));

                        world.addConstraint(c1);
                        world.addConstraint(c2);
                    }
                    else
                    {
                        mass = 0.3;
                    }
                    last = boxbody;
                }
            }
            #endregion

            #endregion


            var dt = 1.0 / 60;
            controls.enabled = true;

            // vr and tilt shift?

            Native.window.onframe += delegate
            {
                if (controls.enabled)
                {
                    // how big of a world can we hold?
                    // async ?
                    world.step(dt);

                    // Update ball positions
                    for (var i = 0; i < balls.Count; i++)
                    {
                        balls[i].position.copy(ballMeshes[i].position);
                        balls[i].quaternion.copy(ballMeshes[i].quaternion);
                    }

                    // Update box positions
                    for (var i = 0; i < boxes.Count; i++)
                    {
                        boxes[i].position.copy(boxMeshes[i].position);
                        boxes[i].quaternion.copy(boxMeshes[i].quaternion);
                    }
                }

                controls.update(Date_now() - time);
                renderer.render(scene, camera);
                time = Date_now();
            };



            #region havePointerLock

            renderer.domElement.onclick +=
                delegate
            {
                renderer.domElement.requestPointerLock();
            };


            #endregion



            #region onmousedown
            renderer.domElement.onmousedown +=
                e =>
            {
                if (e.MouseButton == IEvent.MouseButtonEnum.Middle)
                {
                    if (Native.document.pointerLockElement == Native.document.body)
                    {
                        // cant requestFullscreen while pointerLockElement
                        Console.WriteLine("exitPointerLock");
                        Native.document.exitPointerLock();
                        Native.document.exitFullscreen();
                        return;
                    }

                    Console.WriteLine("requestFullscreen");
                    renderer.domElement.requestFullscreen();
                    renderer.domElement.requestPointerLock();
                    return;
                }

                var ballradius = 0.1 + Math_random() * 0.9;

                var ballShape      = new CANNON.Sphere(ballradius);
                var ballGeometry   = new THREE.SphereGeometry(ballShape.radius, 32, 32);
                var shootDirection = new THREE.Vector3();
                var shootVelo      = 15;
                var projector      = new THREE.Projector();

                Action <THREE.Vector3> getShootDir = (targetVec) =>
                {
                    var vector = targetVec;
                    targetVec.set(0, 0, 1);
                    projector.unprojectVector(vector, camera);
                    var ray = new THREE.Ray((THREE.Vector3)(object) controls_sphereBody.position,
                                            vector
                                            //.subSelf(controls_sphereBody.position)
                                            .normalize()

                                            );
                    targetVec.x = ray.direction.x;
                    targetVec.y = ray.direction.y;
                    targetVec.z = ray.direction.z;
                };


                var x = controls_sphereBody.position.x;
                var y = controls_sphereBody.position.y;
                var z = controls_sphereBody.position.z;

                // could we attach physics via binding list?
                var ballBody = new CANNON.RigidBody(1, ballShape);
                var ballMesh = new THREE.Mesh(ballGeometry, material);
                world.add(ballBody);
                scene.add(ballMesh);
                ballMesh.castShadow    = true;
                ballMesh.receiveShadow = true;
                balls.Add(ballBody);
                ballMeshes.Add(ballMesh);
                getShootDir(shootDirection);
                ballBody.velocity.set(shootDirection.x * shootVelo,
                                      shootDirection.y * shootVelo,
                                      shootDirection.z * shootVelo);

                //        // Move the ball outside the player sphere
                x += shootDirection.x * (controls_sphereShape.radius + ballShape.radius);
                y += shootDirection.y * (controls_sphereShape.radius + ballShape.radius);
                z += shootDirection.z * (controls_sphereShape.radius + ballShape.radius);
                ballBody.position.set(x, y, z);
                ballMesh.position.set(x, y, z);
                //ballMesh.useQuaternion = true;
            };
            #endregion



            //var ze = new ZeProperties();

            //ze.Show();

            //ze.Left = 0;

            //ze.Add(() => renderer);
            //ze.Add(() => controls);
            //ze.Add(() => scene);
        }