<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<canvas id='canvasid' width="3600" height="3600"></canvas>
<input type="file" οnchange="upload(this)" />
</body>
<script src='lib/cuon-matrix.js'></script>
<script src='lib/cuon-utils.js'></script>
<script src='lib/webgl-debug.js'></script>
<script src='lib/webgl-utils.js'></script>
<script type='x-webgl/x-vertex-shader' id='vertexShader'>
attribute vec4 a_Position;
//试图矩阵 视点 观察目标点 方向
uniform mat4 u_ViewMatrix;
//创建可视空间矩阵
uniform mat4 u_ProjMatrix;
//法向量
attribute vec4 a_Normal;
//光线颜色
uniform vec3 u_LightColor;
//归一化世界坐标
uniform vec3 u_LightDirection;
//栅格化颜色
varying vec4 v_Color;
void main(){
gl_Position = u_ViewMatrix * a_Position;
}
</script>
<script type='x-webgl/x-fragment-shader' id='fragmentShader'>
precision mediump float;
uniform vec4 u_FragColor;
void main(){
gl_FragColor = u_FragColor;
}
</script>
<script>
function upload(input) {
//支持chrome IE10
if (window.FileReader) {
var file = input.files[0];
filename = file.name.split(".")[0];
var reader = new FileReader();
reader.onload = function() {
var plyStr = this.result;
var poinsArray = plyStr.split(/[\n]/);
var pointsSize = 0; //顶点数量
var pointStartIndex = 0;//顶点开始数据位置
var pointEndIndex = 0;//顶点结束数据位置
var faceSize = 0; //面数量
var faceStartIndex = 0;//面开始数据位置
var faceEndIndex = 0;//面结束数据位置
var pointArray = [];
var points = [];
var xMax = 0;
var xMin = 0;
var yMax = 0;
var yMin = 0;
var zMax = 0;
var zMin = 0;
for(var i = 0 ; i < poinsArray.length ; i++){
//获取点顶点数量
if(poinsArray[i].indexOf('element')>-1 && poinsArray[i].indexOf('vertex')>-1){
pointsSize = parseFloat(poinsArray[i].substring(poinsArray[i].lastIndexOf(' ')+1,poinsArray.length));
}
//获取面数量
if(poinsArray[i].indexOf('element')>-1 && poinsArray[i].indexOf('face')>-1){
faceSize = parseFloat(poinsArray[i].substring(poinsArray[i].lastIndexOf(' ')+1,poinsArray.length));
}
//end_header 头部 定义 顶点区域 和 面区域
if(poinsArray[i]=='end_header'){
pointStartIndex = i+1;
pointEndIndex = i+pointsSize;
faceStartIndex = pointEndIndex+1;
faceEndIndex = pointEndIndex+faceSize;
}
//加载顶点放入数组
if(pointStartIndex!=0 && pointStartIndex <= i && pointEndIndex >= i){
var pointVec3 = poinsArray[i].split(' ')
var floatpointVec3 = pointVec3.map(function(data){
return parseFloat(data);
});
if(floatpointVec3[0]>xMax){
xMax = floatpointVec3[0]
}
if(floatpointVec3[0]<xMin){
xMin = floatpointVec3[0]
}
if(floatpointVec3[1]>yMax){
yMax = floatpointVec3[1]
}
if(floatpointVec3[1]<yMin){
yMin = floatpointVec3[1]
}
if(floatpointVec3[2]>zMax){
zMax = floatpointVec3[2]
}
if(floatpointVec3[2]<zMin){
zMin = floatpointVec3[2]
}
pointArray.push(floatpointVec3);
}
//加载平面放入数组
if(pointArray.length!=0 && faceStartIndex <= i && faceEndIndex >= i){
var faceitem = poinsArray[i].split(' ');
var intfaceitem = faceitem.map(function(data){
return parseInt(data);
});
var itemSize = intfaceitem[0];//多边形边数
for(var j=1 ; j<=itemSize ; j++){
if(j==itemSize-1){//倒数第二个点结束
break;
}
//获取三点的法向量
var point1 = pointArray[intfaceitem[j]];
var point2 = pointArray[intfaceitem[j+1]];
var point3 = pointArray[intfaceitem[j+2]];
var vector = getVector(point1[0],point1[1],point1[2],point2[0],point2[1],point2[2],point3[0],point3[1],point3[2])
//插入三点
points.push(pointArray[intfaceitem[j]][0],pointArray[intfaceitem[j]][1],pointArray[intfaceitem[j]][2]);
points.push(pointArray[intfaceitem[j+1]][0],pointArray[intfaceitem[j+1]][1],pointArray[intfaceitem[j+1]][2]);
points.push(pointArray[intfaceitem[j+2]][0],pointArray[intfaceitem[j+2]][1],pointArray[intfaceitem[j+2]][2]);
}
}
}
//获取定点坐标
console.log(points);
console.log(xMax);
console.log(xMin);
console.log(yMax);
console.log(yMin);
console.log(zMax);
console.log(zMin);
//获取webGl上下文
var canvasDom = document.getElementById('canvasid');
var gl = canvasDom.getContext('experimental-webgl');
gl.clearColor(202/255,235/225,216/225,1);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
//gl.viewport(0,0,canvasDom.width,canvasDom.height);
//初始化顶点找色器和片元找色器
var vertexGlsl = document.getElementById('vertexShader').text;
var fragmentGlsl = document.getElementById('fragmentShader').text;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader,vertexGlsl);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader,fragmentGlsl);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
//调试程序
if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){
console.log(gl.getShaderInfoLog(vertexShader));
}
if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
console.log(gl.getShaderInfoLog(fragmentShader));
}
var mathmax = Math.max(Math.abs(xMax),Math.abs(yMax),Math.abs(zMax),Math.abs(xMin),Math.abs(yMin),Math.abs(zMin));
var enumPoins = points.map(function(data){
return data/mathmax;
});
var vertexs = new Float32Array(enumPoins);
//设置试图矩阵参数
var u_ViewMatrix = gl.getUniformLocation(program,'u_ViewMatrix');
var viewMatrix = new Matrix4();
viewMatrix.setLookAt(0,0,0,0,0,-1,0,1,0);
gl.uniformMatrix4fv(u_ViewMatrix,false,viewMatrix.elements);
//创建可视范围矩阵
var u_ProjMatrix = gl.getUniformLocation(program,'u_ProjMatrix');
var projMatrix = new Matrix4();
projMatrix.setOrtho(-1.0,1.0,-1.0,1.0,1.0,-1.0);
gl.uniformMatrix4fv(u_ProjMatrix,false,projMatrix.elements);
//创建缓冲区
var vertexBuffer = gl.createBuffer();
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//向缓冲区中写入数据
gl.bufferData(gl.ARRAY_BUFFER,vertexs,gl.STATIC_DRAW);
//获取找色器变量
var a_Position = gl.getAttribLocation(program,'a_Position');
//将缓冲区分配给找色器变量
gl.vertexAttribPointer(a_Position,3,gl.FLOAT,false,0,0);
//连接找色器变量和分配给他的缓冲区对象
gl.enableVertexAttribArray(a_Position);
//找色uniform变量定义颜色
var u_FragColor = gl.getUniformLocation(program,'u_FragColor');
gl.uniform4f(u_FragColor,88/225,87/225,86/225,1.0);
var sizep = vertexs.length/3;
gl.drawArrays(gl.TRIANGLES,0,sizep);
}
reader.readAsText(file);
}
}
/**
* 计算法向量
*/
function getVector(x1,y1,z1,x2,y2,z2,x3,y3,z3){
var x = (y2-y1)*(z3-z1)-(y3-y1)*(z2-z1)
var y = (z2-z1)*(x3-x1)-(z3-z1)*(x2-x1)
var z = (x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)
return [x,y,z];
}
</script>
</html>
点云 ply 文件读取 与 3D处理 (光照,阴影待完善,旋转标注等功能尽情期待)
最新推荐文章于 2024-12-11 23:10:24 发布