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