使用three.js的正X-Y坐标图

时间:2014-02-27 06:28:19

标签: javascript three.js coordinates

我想使用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);

};

1 个答案:

答案 0 :(得分: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)中,我收集用户提供的数据并相应地计算坐标 同样,代码并不完整,但我在这里提供了这个想法。