2014-02-27 66 views
-2

我想使用three.js以網格格式創建正X-Y平面。此外,我希望能夠點擊任何交點並獲取座標值。該視圖應該像一個方格紙。使用three.js的正X-Y座標圖

Design.prototype.mouseUp = function (event) { 

    var material = new THREE.LineDashedMaterial({ 
     color:0xffeedd , dashSize:2 , gapSize:2 
    }); 
    this.container.offsetHeight = 30 , this.container.offsetWidth = 70; 
    var a = 0; 
    for(var i = 0; i <= this.container.offsetWidth ; i++) { 
     var geometry = new THREE.Geometry(); 
     geometry.vertices.push(new THREE.Vector3(-90 + a,-50, 0)); 
     geometry.vertices.push(new THREE.Vector3(-90 + a, 50, 0)); 

     var line = new THREE.Line(geometry, material); 
     this.scene.add(line); 
     a = a + 1; 
    } 

    var b = 0; 
    for(var j = 0; j <= this.container.offsetHeight; j++) { 
     var geometry1 = new THREE.Geometry(); 
     geometry1.vertices.push(new THREE.Vector3(-90,-50 +b , 0)); 
     geometry1.vertices.push(new THREE.Vector3( 90,-50 +b , 0)); 

     var line1 = new THREE.Line(geometry1, material); 
     this.scene.add(line1); 
     b = b + 1; 
    } 

}; 

Design.prototype.onDocumentMouseMove = function(event) { 

    mouseX = event.clientX - (this.container.offsetWidth * 0.5); 
    mouseY = event.clientY - (this.container.offsetHeight-window.innerHeight * 0.875); 

}; 

Design.prototype.onDocumentMouseDown = function(event) { 

    event.preventDefault(); 
    alert("X: " + mouseX + " Y: " + mouseY); 
    var projector = new THREE.Projector(); 
    var vector = new THREE.Vector3((mouseX/this.container.offsetWidth)*(2-1), - (mouseY/this.container.offsetHeight)*(2+1), 0.5); 
    projector.unprojectVector(vector, camera); 

    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize()); 
    var intersects = raycaster.intersectObjects(objects); 

    if (intersects.length > 0){ 

     var sphere = new THREE.Mesh(new THREE.SphereGeometry(size/4), new THREE.MeshLambertMaterial(intensity)); 
     sphere.position = intersects[ 0 ].point; 
     scene.add(sphere); 
    } 
}; 

//three.js code 

window.vv = {}; 
window.vv.messages = { 

NO_CONTAINER: "No Container provided." 
}; 
function DesignSpace() { 

    this.activeDesign = 0; 
this.designes = []; 
} 

DesignSpace.prototype.getDesignByIndex = function(index) { 

    var returnValue = null; 
if (index < this.designes.length) { 
    returnValue = this.designes[index]; 
} 
return returnValue; 
}; 

DesignSpace.prototype.setActiveDesign = function(index) { 

this.activeDesign = index; 
}; 

DesignSpace.prototype.addDesign = function(container) { 

var design = new Design(container); 
this.designes.push(design); 
return design; 
}; 

DesignSpace.prototype.run = function() { 

var design = window.vv.designSpace.getDesignByIndex(window.vv.designSpace.activeDesign); 
design.getRenderer().render(design.getScene(), design.getCamera()); 
window.requestAnimationFrame(window.vv.designSpace.run); 
}; 

function Design(container) { 

this.renderer = null, 
this.scene = null, 
this.camera = null, 
this.cube = null, 
this.animating = null, 
this.light = []; 
this.grid = null; 
this.container = container; 
} 

Design.prototype.setUp = function() { 

if (!this.container) { 
    console.log(window.vv.NO_CONTAINER); 
    return null; 
} 
this.container = document.getElementById(this.container); 
this.renderer = new THREE.WebGLRenderer({antialias: true}); 
this.renderer.setSize(this.container.offsetHeight, this.container.offsetHeight); 
this.container.appendChild(this.renderer.domElement); 


this.scene = new THREE.Scene(); 

this.camera = new THREE.PerspectiveCamera(90, this.container.offsetWidth/this.container.offsetHeight, 1, 4000); 
this.camera.position.set(0, 0, 3); 

if (this.light && !this.light.length) { 

    this.light.push(new Light({intensity: 1.0, x: 0, y: 1, z:1})); 
} 
for (var i in this.light) { 

    this.scene.add(this.light[i].getLight()); 
} 

this.addMouseHandler(); 

}; 
Design.prototype.addMouseHandler = function (event) { 

this.renderer.domElement.addEventListener('mouseup', $.proxy(this.mouseUp, this), false); 
this.renderer.domElement.addEventListener('mousemove', $.proxy(this.onDocumentMouseMove, this), false); 
this.renderer.domElement.addEventListener('mousedown', $.proxy(this.onDocumentMouseDown, this), false); 

}; 
+0

X,Y,Z座標總是從畫布中心開始。你想從中心開始你的飛機並佔據右上象限嗎?或者你希望它佔據整個畫布? –

+0

SO不能這樣工作。你應該做點什麼,然後人們會幫助你。在這裏訂購將無處可去。 – Farzad

+0

@Farzad我的不好。張貼在匆忙。請記住下次:) – user3359133

回答

0

我根本無法遵循你的代碼,所以想出了這樣的事情。它不完整,仍然需要努力。但在我看來,這足以表達這個想法。

<!DOCTYPE html> 
<html> 
<head> 
    <title>simple X-Y coordinate example with shader</title> 
    <style>canvas { width: 100%; height: 100% ;}</style> 
    <style> 
     body { 
      margin: 0px; 
      overflow: hidden; 
     } 
    </style> 
</head> 
<body>  
<script src="https://rawgithub.com/mrdoob/three.js/master/build/three.min.js"></script> 

<script id="vs" type="x-shader/x-vertex">  
    void main() 
    { 
     gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); 
    }   
</script> 

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

    uniform vec2 resolution; 
    #define SCALES 5.0 
    #define X_AXIS -5.0 
    #define Y_AXIS -5.0 
    #define AXIS_THICKNESS 0.08 
    #define ORIGIN_INTENSITY 0.40 

    void main() 
    { 
     vec2 point = -1.0 + 2.0 * (gl_FragCoord.xy/resolution.xy); 
     float aspect_ratio = resolution.x/resolution.y; 
     float r = length (point); 
     vec3 background = (1.0 - 0.15*r) * vec3(0.7-0.07*(point.y+1.0), 0.8, 1.0); 
     vec3 col = vec3(1.0); 

     point *= SCALES; 
     float f = 1.0 - min (
      min(abs(aspect_ratio*point.x - ceil(aspect_ratio*point.x)), abs(aspect_ratio*point.x - floor(aspect_ratio*point.x))), 
      min(abs(point.y - ceil(point.y)), abs(point.y - floor(point.y)))); 
     col *= (1.0 - pow(f, 40.0)); 

     col = (abs(aspect_ratio*point.x - aspect_ratio*X_AXIS)<AXIS_THICKNESS || abs(point.y - Y_AXIS)<AXIS_THICKNESS) ? vec3(0.0) : col; 
     col = (length (vec2(aspect_ratio*point.x, point.y) - vec2(aspect_ratio*X_AXIS, Y_AXIS)) < ORIGIN_INTENSITY) ? vec3(0.0) : col; 

     gl_FragColor = vec4(col*background , 1.0); 
    } 

</script> 

<script type="text/javascript"> 

    var scene = new THREE.Scene(); 
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 
    var renderer = new THREE.WebGLRenderer({ antialias: true}); 

    window.addEventListener('mousedown', onMousePress, false); 

    //assignings happen here 
    //more info on https://github.com/mrdoob/three.js/wiki/Uniforms-types 
    var uniforms = { 
     resolution: { 
      type: "v2", 
      value: new THREE.Vector2(window.innerWidth, window.innerHeight) 
     } 
    }; 
    var myMaterial = new THREE.ShaderMaterial({ 
     uniforms: uniforms, 
     vertexShader: document.getElementById('vs').textContent, 
     fragmentShader: document.getElementById('fs').textContent 
    }); 

    camera.position.z = 0.40; 
    var itemGeometry = new THREE.PlaneGeometry(window.innerWidth/(window.innerWidth+window.innerHeight), window.innerHeight/(window.innerWidth+window.innerHeight), 0); 
    var itemCube = new THREE.Mesh(itemGeometry, myMaterial); 
    scene.add(itemCube); 

    renderer.setSize(window.innerWidth, window.innerHeight); 
    document.body.appendChild(renderer.domElement); 


    function onWindowResize() { 

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

     renderer.setSize(window.innerWidth, window.innerHeight); 
     uniforms.resolution.value = new THREE.Vector2(window.innerWidth, window.innerHeight); 

    } 

    function onMousePress(e){ 
     var scale = 10; 
     var aspect = window.innerWidth/window.innerHeight; 
     alert(scale*aspect* (e.clientX/window.innerWidth)); 
     alert(scale* ((window.innerHeight - e.clientY)/ window.innerHeight)); 
    } 

    function render() { 

     requestAnimationFrame(render);  
     renderer.render(scene, camera); 

    } 
    render(); 
</script> 
</body> 
</html> 

我已經定義了一個具有平面幾何和自定義着色器的平面網格。在片段着色器中,我繪製了類似方格紙的平面。您可以使用參數來查看它們如何影響最終結果。在JavaScript代碼中,請參閱onWindowResize()。這是我將窗口大小更改應用到相機,渲染器以及更新片段着色器參數的地方。在onMousePress(e)中,我收集用戶提供的數據並相應地計算座標。
同樣,代碼不完整,但我在這裏提供給你的想法。

+0

謝謝!代碼真的很有用。此代碼在整個窗口中展開。我可以在容器中實現相同的代碼嗎? – user3359133

+0

爲了使原點(0,0)突出,表示X和Y軸的2條射線是必要的。我可以使用下面的代碼來創建X軸嗎? var origin = new Vector3(0,0,0); var dest = new Vector(20,0,0); dest.normalize(); var ray = new Ray(origin,dest); – user3359133

+0

渲染髮生在畫布內。你可以使用純CSS來指定它的位置和大小。在上面的代碼中,它佔據了其父代的寬度和大小的100%(在CSS層次結構中)。小心如果你這樣做,你必須重新考慮和重寫書面鼠標事件功能。 – Farzad