2014-03-06 17 views
-1

可旋轉3D模型我有相當有點不知所措:在網頁

我要創建的人體三維模型,將其嵌入到一個網頁,併爲用戶提供旋轉的能力。我已經考慮了一些建模庫,CSS,SVG等(我從來沒有用過HTML5 Canvas),但說實話我不確定這是否可能。

另外 - 如果上述可能,那麼是否可以操縱關節,例如將膝蓋擡起或肘部進入?

我的主要想法是在SVG中構建模型,並讓模型通過Javascript以36度的角度旋轉,然後可以從那裏操縱關節。

如果需要,我願意學習新的語言來做到這一點。

在此先感謝,希望有人能幫助我。即使告訴我這是不可能的。

約翰

+0

有什麼代碼可以使用嗎? –

+0

無我害怕,因爲我不知道從哪裏開始。我不想輸入數據只是爲了找到我使用的技術不起作用,因此我試圖建立我需要儘早使用的技術。 –

+0

我在Twitter上建議使用[threejs.org](http://threejs.org)。如果沒有更好的來自這個線程,我將添加這個答案,因爲它看起來像一個理想的起點:-) –

回答

1

硬而美的方式:THREEJS。簡單的方法:創建一個圖像,每個框架將其設置爲容器中的背景,然後相應地更改背景位置(這將允許僅在一個軸上旋轉,並且不允許關節操作)。

我建議你學習threejs(如果你有足夠的時間),他們的例子很好,並不難。

瀏覽器支持在您的選擇中也起着重要作用,threejs使用畫布,所以它是一個非常新的功能。你可以同時使用這兩種解決方案,在新的瀏覽器上使用threejs,在蹩腳的舊版上使用sprite

+0

感謝Jonas,這是我的個人項目,我非常樂意學習新的技能等,因此學習threejs不會成爲問題。我真誠地沒有看到threejs - 離我最近的是sprite.js。我會接受你的答案爲正確的答案,因爲你是最好的答案和替代方案。再次感謝,約翰 –

1

這段代碼來自three.js,這對於這個問題可能有用。

<!doctype html> 
<html lang="en"> 
    <head> 
     <title>three.js webgl - cloth simulation</title> 
     <meta charset="utf-8"> 
     <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 
     <style> 
      body { 
       font-family: Monospace; 
       background-color: #000; 
       color: #000; 
       margin: 0px; 
       overflow: hidden; 
      } 

      #info { 
       text-align: center; 
       padding: 10px; 
       z-index: 10; 
       width: 100%; 
       position: absolute; 
      } 

      a { 
       text-decoration: underline; 
       cursor: pointer; 
      } 

      #stats { position: absolute; top:0; left: 0 } 
      #stats #fps { background: transparent !important } 
      #stats #fps #fpsText { color: #aaa !important } 
      #stats #fps #fpsGraph { display: none } 
     </style> 
    </head> 

    <body> 
     <div id="info">Simple Cloth Simulation<br/> 
      Verlet integration with Constrains relaxation<br/> 
      Toggle: <a onclick="rotate = !rotate;">Camera</a> | 
      <a onclick="wind = !wind;">Wind</a> | 
      <a onclick="sphere.visible = !sphere.visible;">Ball</a> | 
      <a onclick="togglePins();">Pins</a> 
     </div> 

     <script src="../build/three.min.js"></script> 

     <script src="js/Detector.js"></script> 
     <script src="js/libs/stats.min.js"></script> 

     <script src="js/Cloth.js"></script> 

     <script type="x-shader/x-fragment" id="fragmentShaderDepth"> 

      uniform sampler2D texture; 
      varying vec2 vUV; 

      vec4 pack_depth(const in float depth) { 

       const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); 
       const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0); 
       vec4 res = fract(depth * bit_shift); 
       res -= res.xxyz * bit_mask; 
       return res; 

      } 

      void main() { 

       vec4 pixel = texture2D(texture, vUV); 

       if (pixel.a < 0.5) discard; 

       gl_FragData[ 0 ] = pack_depth(gl_FragCoord.z); 

      } 
     </script> 

     <script type="x-shader/x-vertex" id="vertexShaderDepth"> 

      varying vec2 vUV; 

      void main() { 

       vUV = 0.75 * uv; 

       vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 

       gl_Position = projectionMatrix * mvPosition; 

      } 

     </script> 

     <script> 

      /* testing cloth simulation */ 

      var pinsFormation = []; 
      var pins = [6]; 

      pinsFormation.push(pins); 

      pins = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; 
      pinsFormation.push(pins); 

      pins = [ 0 ]; 
      pinsFormation.push(pins); 

      pins = []; // cut the rope ;) 
      pinsFormation.push(pins); 

      pins = [ 0, cloth.w ]; // classic 2 pins 
      pinsFormation.push(pins); 

      pins = pinsFormation[ 1 ]; 


      function togglePins() { 

       pins = pinsFormation[ ~~(Math.random() * pinsFormation.length) ]; 

      } 

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

      var container, stats; 
      var camera, scene, renderer; 

      var clothGeometry; 
      var sphere; 
      var object, arrow; 

      var rotate = true; 

      init(); 
      animate(); 

      function init() { 

       container = document.createElement('div'); 
       document.body.appendChild(container); 

       // scene 

       scene = new THREE.Scene(); 

       scene.fog = new THREE.Fog(0xcce0ff, 500, 10000); 

       // camera 

       camera = new THREE.PerspectiveCamera(30, window.innerWidth/window.innerHeight, 1, 10000); 
       camera.position.y = 50; 
       camera.position.z = 1500; 
       scene.add(camera); 

       // lights 

       var light, materials; 

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

       light = new THREE.DirectionalLight(0xdfebff, 1.75); 
       light.position.set(50, 200, 100); 
       light.position.multiplyScalar(1.3); 

       light.castShadow = true; 
       //light.shadowCameraVisible = true; 

       light.shadowMapWidth = 2048; 
       light.shadowMapHeight = 2048; 

       var d = 300; 

       light.shadowCameraLeft = -d; 
       light.shadowCameraRight = d; 
       light.shadowCameraTop = d; 
       light.shadowCameraBottom = -d; 

       light.shadowCameraFar = 1000; 
       light.shadowDarkness = 0.5; 

       scene.add(light); 

       light = new THREE.DirectionalLight(0x3dff0c, 0.35); 
       light.position.set(0, -1, 0); 

       scene.add(light); 

       // cloth material 

       var clothTexture = THREE.ImageUtils.loadTexture('textures/patterns/circuit_pattern.png'); 
       clothTexture.wrapS = clothTexture.wrapT = THREE.RepeatWrapping; 
       clothTexture.anisotropy = 16; 

       var clothMaterial = new THREE.MeshPhongMaterial({ alphaTest: 0.5, ambient: 0xffffff, color: 0xffffff, specular: 0x030303, emissive: 0x111111, shiness: 10, map: clothTexture, side: THREE.DoubleSide }); 

       // cloth geometry 
       clothGeometry = new THREE.ParametricGeometry(clothFunction, cloth.w, cloth.h); 
       clothGeometry.dynamic = true; 
       clothGeometry.computeFaceNormals(); 

       var uniforms = { texture: { type: "t", value: clothTexture } }; 
       var vertexShader = document.getElementById('vertexShaderDepth').textContent; 
       var fragmentShader = document.getElementById('fragmentShaderDepth').textContent; 

       // cloth mesh 

       object = new THREE.Mesh(clothGeometry, clothMaterial); 
       object.position.set(0, 0, 0); 
       object.castShadow = true; 
       object.receiveShadow = true; 
       scene.add(object); 

       object.customDepthMaterial = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader }); 

       // sphere 

       var ballGeo = new THREE.SphereGeometry(ballSize, 20, 20); 
       var ballMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff }); 

       sphere = new THREE.Mesh(ballGeo, ballMaterial); 
       sphere.castShadow = true; 
       sphere.receiveShadow = true; 
       scene.add(sphere); 

       // arrow 

       arrow = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), 50, 0xff0000); 
       arrow.position.set(-200, 0, -200); 
       // scene.add(arrow); 

       // ground 

       var initColor = new THREE.Color(0x497f13); 
       var initTexture = THREE.ImageUtils.generateDataTexture(1, 1, initColor); 

       var groundMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0x111111, map: initTexture }); 

       var groundTexture = THREE.ImageUtils.loadTexture("textures/terrain/grasslight-big.jpg", undefined, function() { groundMaterial.map = groundTexture }); 
       groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping; 
       groundTexture.repeat.set(25, 25); 
       groundTexture.anisotropy = 16; 

       var mesh = new THREE.Mesh(new THREE.PlaneGeometry(20000, 20000), groundMaterial); 
       mesh.position.y = -250; 
       mesh.rotation.x = - Math.PI/2; 
       mesh.receiveShadow = true; 
       scene.add(mesh); 

       // poles 

       var poleGeo = new THREE.BoxGeometry(5, 375, 5); 
       var poleMat = new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0x111111, shiness: 100 }); 

       var mesh = new THREE.Mesh(poleGeo, poleMat); 
       mesh.position.x = -125; 
       mesh.position.y = -62; 
       mesh.receiveShadow = true; 
       mesh.castShadow = true; 
       scene.add(mesh); 

       var mesh = new THREE.Mesh(poleGeo, poleMat); 
       mesh.position.x = 125; 
       mesh.position.y = -62; 
       mesh.receiveShadow = true; 
       mesh.castShadow = true; 
       scene.add(mesh); 

       var mesh = new THREE.Mesh(new THREE.BoxGeometry(255, 5, 5), poleMat); 
       mesh.position.y = -250 + 750/2; 
       mesh.position.x = 0; 
       mesh.receiveShadow = true; 
       mesh.castShadow = true; 
       scene.add(mesh); 

       var gg = new THREE.BoxGeometry(10, 10, 10); 
       var mesh = new THREE.Mesh(gg, poleMat); 
       mesh.position.y = -250; 
       mesh.position.x = 125; 
       mesh.receiveShadow = true; 
       mesh.castShadow = true; 
       scene.add(mesh); 

       var mesh = new THREE.Mesh(gg, poleMat); 
       mesh.position.y = -250; 
       mesh.position.x = -125; 
       mesh.receiveShadow = true; 
       mesh.castShadow = true; 
       scene.add(mesh); 

       // 

       renderer = new THREE.WebGLRenderer({ antialias: true }); 
       renderer.setSize(window.innerWidth, window.innerHeight); 
       renderer.setClearColor(scene.fog.color); 

       container.appendChild(renderer.domElement); 

       renderer.gammaInput = true; 
       renderer.gammaOutput = true; 

       renderer.shadowMapEnabled = true; 

       // 

       stats = new Stats(); 
       container.appendChild(stats.domElement); 

       // 

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

       sphere.visible = !true 

      } 

      // 

      function onWindowResize() { 

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

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

      } 

      // 

      function animate() { 

       requestAnimationFrame(animate); 

       var time = Date.now(); 

       windStrength = Math.cos(time/7000) * 20 + 40; 
       windForce.set(Math.sin(time/2000), Math.cos(time/3000), Math.sin(time/1000)).normalize().multiplyScalar(windStrength); 
       arrow.setLength(windStrength); 
       arrow.setDirection(windForce); 

       simulate(time); 
       render(); 
       stats.update(); 

      } 

      function render() { 

       var timer = Date.now() * 0.0002; 

       var p = cloth.particles; 

       for (var i = 0, il = p.length; i < il; i ++) { 

        clothGeometry.vertices[ i ].copy(p[ i ].position); 

       } 

       clothGeometry.computeFaceNormals(); 
       clothGeometry.computeVertexNormals(); 

       clothGeometry.normalsNeedUpdate = true; 
       clothGeometry.verticesNeedUpdate = true; 

       sphere.position.copy(ballPosition); 

       if (rotate) { 

        camera.position.x = Math.cos(timer) * 1500; 
        camera.position.z = Math.sin(timer) * 1500; 

       } 

       camera.lookAt(scene.position); 

       renderer.render(scene, camera); 

      } 

     </script> 
    </body> 
</html> 
+0

嗨Karthik,謝謝你提供的代碼。我今晚會去學習三節課,並將剖析他們所擁有的例子,並逐漸建立我需要的模型。謝謝你 –