Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript WebGl:使对象一起移动和单独移动_Javascript_Webgl - Fatal编程技术网

Javascript WebGl:使对象一起移动和单独移动

Javascript WebGl:使对象一起移动和单独移动,javascript,webgl,Javascript,Webgl,我正在尝试制作一个机器人,它使用滑块将身体一起旋转,身体各部分一起和分开移动,即移动上臂移动整个手臂,旋转身体旋转每个身体部分。但我也希望身体各部分分开移动,比如头部移动和下臂自身移动 我的问题是,并不是所有的对象都出现了,只有前3个对象,我觉得这与滑块使用θ有关。当我移动头部时,手臂也会移动。我知道它与模型视图矩阵有关,我所做的每一次转换都会继续应用于其余部分,但当我尝试使用pop()和push()时,它会使对象消失或冻结,无法移动。有人能给我指出正确的方向吗?我包含了大部分代码,但不是所有的

我正在尝试制作一个机器人,它使用滑块将身体一起旋转,身体各部分一起和分开移动,即移动上臂移动整个手臂,旋转身体旋转每个身体部分。但我也希望身体各部分分开移动,比如头部移动和下臂自身移动

我的问题是,并不是所有的对象都出现了,只有前3个对象,我觉得这与滑块使用θ有关。当我移动头部时,手臂也会移动。我知道它与模型视图矩阵有关,我所做的每一次转换都会继续应用于其余部分,但当我尝试使用pop()和push()时,它会使对象消失或冻结,无法移动。有人能给我指出正确的方向吗?我包含了大部分代码,但不是所有的变量

var theta = [0,0,0];

function scale4(a, b, c) {
  var result = mat4();
  result[0][0] = a;
  result[1][1] = b;
  result[2][2] = c;
  return result;
}

window.onload = function init()
{
  var canvas = document.getElementById( "webgl-robot" );

  gl = WebGLUtils.setupWebGL( canvas );
  if ( !gl ) { alert( "WebGL isn't available" ); }

  gl.viewport( 0, 0, canvas.width, canvas.height );
  gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
  gl.enable( gl.DEPTH_TEST ); 

  program = initShaders( gl, "vertex-shader", "fragment-shader" ); 
  gl.useProgram( program);

  colorCube();

  program = initShaders( gl, "vertex-shader", "fragment-shader" );    
  gl.useProgram( program );


  var vBuffer = gl.createBuffer();
  gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
  gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.DYNAMIC_DRAW );

  var vPosition = gl.getAttribLocation( program, "vPosition" );
  gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
  gl.enableVertexAttribArray( vPosition );

  var cBuffer = gl.createBuffer();
  gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
  gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.DYNAMIC_DRAW );

  var vColor = gl.getAttribLocation( program, "vColor" );
  gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
  gl.enableVertexAttribArray( vColor );

  modelView = gl.getUniformLocation( program, "modelView" );
  projection = gl.getUniformLocation( program, "projection" );

  document.getElementById("slider1").onchange = function() {
    theta[0] = event.srcElement.value;
  };
  document.getElementById("slider2").onchange = function() {
     theta[1] = event.srcElement.value;
  };
  document.getElementById("slider3").onchange = function() {
     theta[2] =  event.srcElement.value;
  };
  document.getElementById("slider4").onchange = function() {
     theta[3] = event.srcElement.value;
  };
  document.getElementById("slider5").onchange = function() {
     theta[4] = event.srcElement.value;
  };

  modelView2 = gl.getUniformLocation( program, "modelView" );
  projection2 = gl.getUniformLocation( program, "projection" );

  modelViewMatrixLoc = gl.getUniformLocation( program, "modelViewMatrix");
  projection = gl.getUniformLocation( program, "projection" );

  projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
  gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"),  
  false, flatten(projectionMatrix) );

  render();
}

function base() {
   var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH);
   var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
   var t = mult(modelViewMatrix, instanceMatrix);
   gl.uniformMatrix4fv(modelViewMatrixLoc,  false, flatten(t) );
   gl.drawArrays( gl.TRIANGLES, 0, 36 );
}

function head() {
   var s = scale4(HEAD_WIDTH, HEAD_HEIGHT, HEAD_WIDTH);
   var instanceMatrix = mult(translate( 0.0, 0.5 * HEAD_HEIGHT, 0.0 ),s);    
   var t = mult(modelViewMatrix, instanceMatrix);
   gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
   gl.drawArrays( gl.TRIANGLES, 0, 36 );
}

function leftUpperArm()
{
   var s = scale4(LEFT_UPPER_WIDTH, LEFT_UPPER_HEIGHT, LEFT_UPPER_WIDTH);
   var instanceMatrix = mult( translate( 0.0, 0.5 * LEFT_UPPER_HEIGHT, 0.0 ), 
   s);
   var t = mult(modelViewMatrix, instanceMatrix);
   gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
   gl.drawArrays( gl.TRIANGLES, 0, 36 );
}

function leftLowerArm()
{
   var s = scale4(LEFT_LOWER_WIDTH, LEFT_LOWER_HEIGHT, LEFT_LOWER_WIDTH);
   var instanceMatrix = mult( translate( 0.0, 0.5 * LEFT_LOWER_HEIGHT, 0.0 ), 
    s);
   var t = mult(modelViewMatrix, instanceMatrix);
   gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
   gl.drawArrays( gl.TRIANGLES, 0, 36 );
}

function rightUpperArm()
{
   var s = scale4(RIGHT_UPPER_WIDTH, RIGHT_UPPER_HEIGHT, RIGHT_UPPER_WIDTH);
   var instanceMatrix = mult( translate( -9.3, 0.5 * RIGHT_UPPER_HEIGHT, 0.0 
   ), s);
   var t = mult(modelViewMatrix, instanceMatrix);
   gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
   gl.drawArrays( gl.TRIANGLES, 0, 36 );
}

function render() {

  gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );

  modelViewMatrix = rotate(theta[Base], 0, 1, 0 );
  base();

  modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0)); 
  modelViewMatrix = mult(modelViewMatrix, rotate(theta[Head], 0, 0, 1 ));
  head();

  modelViewMatrix  = mult(modelViewMatrix, translate(1.3, -0.7, 0.0));
  modelViewMatrix  = mult(modelViewMatrix, rotate(theta[LeftUpper], 1, 0, 0) 
  );
  leftUpperArm();

  modelViewMatrix = mult(modelViewMatrix, translate(0.0, LEFT_UPPER_HEIGHT, 
  0.0));   
  modelViewMatrix = mult(modelViewMatrix, rotate(theta[LeftLower], 0, 0, 1 ));
  leftLowerArm();

  modelViewMatrix  = mult(modelViewMatrix, translate(5.3, -0.7, 0.0));
  modelViewMatrix  = mult(modelViewMatrix, rotate(theta[RightUpper], 1, 0, 0) 
  );
  rightUpperArm();

  requestAnimFrame(render);
}

制作/移动/设置这样的动画(层次模型)的正常方法是使用和/或

使用矩阵堆栈,从根开始(可以是腰部,也可以是脚之间的一个点),然后遍历角色的树,乘以矩阵

 root
   waist
     left thigh
       left lower leg
          left foot
     right thigh
       right lower leg
          right foot
   stomach
     chest
       left upper arm
          left forearm
             left hand
       right upper arm
          right forearm
             right hand
       neck
         head
           left eye
           right eye
在树中的每个点保存当前模型矩阵(将其推到堆栈上),然后将其向下传递给子对象以添加其方向

这样,如果您移动/旋转胸部,则零件树中更深的所有零件(手臂、颈部、头部)都会随之自动移动/旋转

您可以在下面使用矩阵堆栈的示例中看到。只有胸部设置了动画,但由于矩阵堆栈,手臂和头部随胸部移动

const m4=twgl.m4;
常数v3=twgl.v3;
const gl=document.querySelector(“canvas”).getContext(“webgl”);
常数vs=`
属性向量4位置;
属性向量3正常;
均匀mat4u_投影;
统一的mat4 u_视图;
统一mat4-u_模型;
可变vec3 v_正常;
void main(){
gl_位置=u_投影*u_视图*u_模型*位置;
v_normal=mat3(u_模型)*normal;//最好使用逆转置模型
}
`
常数fs=`
精密中泵浮子;
可变vec3 v_正常;
均匀vec3 u_lightDir;
均匀的vec3u_颜色;
void main(){
浮动灯光=点(标准化(v_法线),u_lightDir)*.5+.5;
gl_FragColor=vec4(u_color*light,1);
}
`;
//编译着色器、链接程序、查找属性
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
//调用gl.createBuffer、gl.bindBuffer、gl.bufferData
const cubeBufferInfo=twgl.primitives.createCubeBufferInfo(gl,1);
常量堆栈=[];
常量颜色=[1,5,3];
const lightDir=v3.normalize([1,5,10]);
函数渲染(时间){
时间*=0.001;
twgl.resizeCanvasToDisplaySize(总图画布);
总图视口(0,0,总图画布宽度,总图画布高度);
总帐启用(总帐深度测试);
总账启用(总账消隐面);
总账使用程序(programInfo.program);
常数fov=Math.PI*.25;
const aspect=gl.canvas.clientWidth/gl.canvas.clientHeight;
常数zNear=0.01;
常数zFar=100;
常量投影=m4.透视图(视野、纵横比、zNear、zFar);
常量cameraPosition=[1,4,10]
常量目标=[0,3,0];
const up=[0,1,0];
常量摄影机=m4.注视(摄影机位置,目标,向上);
常量视图=m4。反向(摄像头);
//确定机器人的基本位置
设m=m4.平移([0,0,0]);
pushMatrix(m);
{
//上身
m=m4.平移(m[0,3,0]);
drawCube(投影、视图,m);
pushMatrix(m);
{
//移到左大腿
m=m4.平移(m[1.1,-.5,0]);
drawCube(投影、视图,m);
pushMatrix(m);
{
//移到左脚
m=m4.平移(m[0,-1.1,0]);
drawCube(投影、视图,m);
}
m=矩阵(m);
}
m=矩阵(m);
pushMatrix(m);
{
//移到右大腿
m=m4.平移(m,[-1.1,-.5,0]);
drawCube(投影、视图,m);
pushMatrix(m);
{
//移到右脚
m=m4.平移(m[0,-1.1,0]);
drawCube(投影、视图,m);
}
m=矩阵(m);
}
m=矩阵(m);
pushMatrix(m);
{
//移到胸部
m=m4.平移(m[0,1.1,0]);
m=m4.rotateY(m,数学sin(时间)*.6);
drawCube(投影、视图,m);
pushMatrix(m);
{
//移到左臂
m=m4.平移(m,[-1.1,0,0]);
drawCube(投影、视图,m);
}
m=矩阵(m);
pushMatrix(m);
{
//移到右臂
m=m4.平移(m[1.1,0,0]);
drawCube(投影、视图,m);
}
m=矩阵(m);
pushMatrix(m);
{
//移动到头部
m=m4.平移(m[0,1.1,0]);
drawCube(投影、视图,m);
}
m=矩阵(m);
}
m=矩阵(m);
}
m=popMatrix();
请求动画帧(渲染);
}
请求动画帧(渲染);
函数矩阵(m){
叠加推力(m);
}
函数矩阵(){
返回stack.pop();
}
函数drawCube(投影、视图、模型){
//没有理由每次都打电话给他们,因为我们总是
//使用同一个立方体,但一个真正的机器人可能会
//每个部分有不同的部分:
//腿,手臂,左手,右脚。。。
//调用gl.bindBuffer、gl.enableVertexAttributeArray、gl.VertexAttributePointer
twgl.setBuffersAndAttributes(总帐、程序信息、立方BufferInfo);
//调用gl.uniformXXX
twgl.设置制服(程序信息{
颜色:颜色,
u_lightDir:lightDir,
u_投影:投影,
视图:视图,
u_模型:模型,
});
//调用gl.DrawArray或gl.drawElements
twgl.drawBufferInfo(gl,cubeBufferInfo);
}
body{margin:0;}
帆布