Пример #1
0
static int luaB_cross (lua_State *L) {
  float x1, y1, z1;
  float x2, y2, z2;
  float ax, ay, az;
  if (lua_gettop(L) != 2) luaL_error(L, "Invalid params, try cross(v,v)");
  lua_checkvector3(L, 1, &x1, &y1, &z1);
  lua_checkvector3(L, 2, &x2, &y2, &z2);
  cross(x1,y1,z1, x2,y2,z2, &ax, &ay, &az);
  lua_pushvector3(L,ax,ay,az);
  return 1;
}
Пример #2
0
static int luaB_unpack (lua_State *L) {
  if (lua_gettop(L)==1 && lua_isvector3(L,1)) {
    float x, y, z; lua_checkvector3(L, 1, &x, &y, &z);
    lua_pushnumber(L,x);
    lua_pushnumber(L,y);
    lua_pushnumber(L,z);
    return 3;
  } else if (lua_gettop(L)==1 && lua_isquat(L,1)) {
    float w, x, y, z; lua_checkquat(L, 1, &w, &x, &y, &z);
    lua_pushnumber(L,w);
    lua_pushnumber(L,x);
    lua_pushnumber(L,y);
    lua_pushnumber(L,z);
    return 4;
  } else {
    int i, e, n;
    luaL_checktype(L, 1, LUA_TTABLE);
    i = luaL_optint(L, 2, 1);
    e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
    if (i > e) return 0;  /* empty range */
    n = e - i + 1;  /* number of elements */
    if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
      return luaL_error(L, "too many results to unpack");
    lua_rawgeti(L, 1, i);  /* push arg[i] (avoiding overflow problems) */
    while (i++ < e)  /* push arg[i + 1...e] */
      lua_rawgeti(L, 1, i);
    return n;
  }
}
Пример #3
0
static int math_abs (lua_State *L) {
  lua_Number v;
  float x, y, z, w;
  switch (lua_type(L,1)) {

    case LUA_TNUMBER:
    if (lua_isinteger(L, 1)) {
      lua_Integer n = lua_tointeger(L, 1);
      if (n < 0) n = (lua_Integer)(0u - n);
      lua_pushinteger(L, n);
	} else {
      v = lua_tonumber(L,1);
      lua_pushnumber(L,l_mathop(fabs)(v));
	}
    return 1;
    case LUA_TVECTOR2:
    lua_checkvector2(L,1,&x,&y);
    lua_pushvector2(L,fabsf(x),fabsf(y));
    return 1;
    case LUA_TVECTOR3:
    lua_checkvector3(L,1,&x,&y,&z);
    lua_pushvector3(L,fabsf(x),fabsf(y),fabsf(z));
    return 1;
    case LUA_TVECTOR4:
    lua_checkvector4(L,1,&x,&y,&z,&w);
    lua_pushvector4(L,fabsf(x),fabsf(y),fabsf(z),fabsf(w));
    return 1;
  }
  luaL_error(L, "abs takes a number, integer, vector2, vector3, or vector4.");
  return 1;
}
Пример #4
0
static int math_ceil (lua_State *L) {
  lua_Number v;
  float x, y, z, w;
  switch (lua_type(L,1)) {
    case LUA_TNUMBER:
    if (lua_isinteger(L, 1)) {
      lua_settop(L, 1); /* integer is its own ceil */
	} else {
      v = lua_tonumber(L,1);
      pushnumint(L,ceil(v));
	}
    return 1;
    case LUA_TVECTOR2:
    lua_checkvector2(L,1,&x,&y);
    lua_pushvector2(L,ceilf(x),ceilf(y));
    return 1;
    case LUA_TVECTOR3:
    lua_checkvector3(L,1,&x,&y,&z);
    lua_pushvector3(L,ceilf(x),ceilf(y),ceilf(z));
    return 1;
    case LUA_TVECTOR4:
    lua_checkvector4(L,1,&x,&y,&z,&w);
    lua_pushvector4(L,ceilf(x),ceilf(y),ceilf(z),ceilf(w));
    return 1;
  }
  luaL_error(L, "ceil takes a number, integer, vector2, vector3, or vector4.");
  return 1;
}
Пример #5
0
static int luaB_dot (lua_State *L) {
  float x1, y1, z1, w1;
  float x2, y2, z2, w2;
  if (lua_gettop(L) != 2) luaL_error(L, "Invalid params, try dot(v,v)");
  if (lua_isvector4(L,1)) {
    lua_checkvector4(L, 1, &x1, &y1, &z1, &w1);
    lua_checkvector4(L, 2, &x2, &y2, &z2, &w2);
    lua_pushnumber(L,dot4(x1,y1,z1,w1, x2,y2,z2,w2));
  } else if (lua_isvector3(L,1)) {
    lua_checkvector3(L, 1, &x1, &y1, &z1);
    lua_checkvector3(L, 2, &x2, &y2, &z2);
    lua_pushnumber(L,dot3(x1,y1,z1, x2,y2,z2));
  } else if (lua_isvector2(L,1)) {
    lua_checkvector2(L, 1, &x1, &y1);
    lua_checkvector2(L, 2, &x2, &y2);
    lua_pushnumber(L,dot2(x1,y1, x2,y2));
  }
  return 1;
}
Пример #6
0
static int math_clamp (lua_State *L) {
  if (lua_gettop(L)!=3) return luaL_error(L, "wrong number of arguments");
  switch (lua_type(L,1)) {
    case LUA_TNUMBER: {
      lua_Number a, b, c;
      a = luaL_checknumber(L,1);
      b = luaL_checknumber(L,2);
      c = luaL_checknumber(L,3);
      if (a<b) a = b;
      if (a>c) a = c;
      lua_pushnumber(L, a);
    } break;
    case LUA_TVECTOR2: {
      float xa, ya;
      float xb, yb;
      float xc, yc;
      lua_checkvector2(L, 1, &xa, &ya);
      lua_checkvector2(L, 2, &xb, &yb);
      lua_checkvector2(L, 3, &xc, &yc);
      lua_pushvector2(L, do_clamp(xa,xb,xc), do_clamp(ya,yb,yc));
    } break;
    case LUA_TVECTOR3: {
      float xa, ya, za;
      float xb, yb, zb;
      float xc, yc, zc;
      lua_checkvector3(L, 1, &xa, &ya, &za);
      lua_checkvector3(L, 2, &xb, &yb, &zb);
      lua_checkvector3(L, 3, &xc, &yc, &zc);
      lua_pushvector3(L, do_clamp(xa,xb,xc), do_clamp(ya,yb,yc), do_clamp(za,zb,zc));
    } break;
    case LUA_TVECTOR4: {
      float xa, ya, za, wa;
      float xb, yb, zb, wb;
      float xc, yc, zc, wc;
      lua_checkvector4(L, 1, &xa, &ya, &za, &wa);
      lua_checkvector4(L, 2, &xb, &yb, &zb, &wb);
      lua_checkvector4(L, 3, &xc, &yc, &zc, &wc);
      lua_pushvector4(L, do_clamp(xa,xb,xc), do_clamp(ya,yb,yc), do_clamp(za,zb,zc), do_clamp(wa,wb,wc));
    } break;
    default: return luaL_error(L, "clamp only works on number, vector2, vector3, vector4");
  }
  return 1;
}
Пример #7
0
static int luaB_vectorn (lua_State *L, int sz, float *input) {
  int counter = 0;
  int i;
  for (i=1; i<=lua_gettop(L) ; ++i) {
    switch (lua_type(L, i)) {
      case LUA_TVECTOR4:
      if (counter+4 <= sz) {
        float *x = &input[counter++];
        float *y = &input[counter++];
        float *z = &input[counter++];
        float *w = &input[counter++];
        lua_checkvector4(L, i, x,y,z,w);
      } else {
        return 0;
      }
      break;

      case LUA_TVECTOR3:
      if (counter+3 <= sz) {
        float *x = &input[counter++];
        float *y = &input[counter++];
        float *z = &input[counter++];
        lua_checkvector3(L, i, x,y,z);
      } else {
        return 0;
      }
      break;

      case LUA_TVECTOR2:
      if (counter+2 <= sz) {
        float *x = &input[counter++];
        float *y = &input[counter++];
        lua_checkvector2(L, i, x,y);
      } else {
        return 0;
      }
      break;

      case LUA_TNUMBER:
      if (counter+1 <= sz) {
        input[counter++] = lua_tonumber(L, i);
      } else {
        return 0;
      }
      break;

      default: {
        char msg[1024];
        sprintf(msg, "vector%d(...) argument %d had type %s", sz, i, lua_typename(L, lua_type(L,i)));
        luaL_error(L, msg);
      }
    }
  }
  return counter == sz;
}
Пример #8
0
static int luaB_norm (lua_State *L) {
  if (lua_gettop(L)==1 && lua_isvector3(L,1)) {
    float x, y, z;
    float len;
    lua_checkvector3(L, 1, &x, &y, &z);
    len = sqrtf(x*x + y*y + z*z);
    lua_pushvector3(L,x/len,y/len,z/len);
    return 1;
  } else if (lua_gettop(L)==1 && lua_isquat(L,1)) {
    float w, x, y, z;
    float qlen;
    lua_checkquat(L, 1, &w, &x, &y, &z);
    qlen = sqrtf(w*w + x*x + y*y + z*z);
    lua_pushquat(L,w/qlen,x/qlen,y/qlen,z/qlen);
    return 1;
  } else {
    luaL_error(L, "Invalid params, try norm(v) norm(q)");
    return 0;
  }
}
Пример #9
0
static int luaB_norm (lua_State *L) {
  if (lua_gettop(L)==1 && lua_isvector2(L,1)) {
    float x, y;
    float len;
    lua_checkvector2(L, 1, &x, &y);
    len = sqrtf(x*x + y*y);
    if (len == 0)
        luaL_error(L, "Cannot normalise vector2(0,0)");
    lua_pushvector2(L,x/len,y/len);
    return 1;
  } else if (lua_gettop(L)==1 && lua_isvector3(L,1)) {
    float x, y, z;
    float len;
    lua_checkvector3(L, 1, &x, &y, &z);
    len = sqrtf(x*x + y*y + z*z);
    if (len == 0)
        luaL_error(L, "Cannot normalise vector3(0,0,0)");
    lua_pushvector3(L,x/len,y/len,z/len);
    return 1;
  } else if (lua_gettop(L)==1 && lua_isvector4(L,1)) {
    float x, y, z, w;
    float len;
    lua_checkvector4(L, 1, &x, &y, &z, &w);
    len = sqrtf(x*x + y*y + z*z + w*w);
    if (len == 0)
        luaL_error(L, "Cannot normalise vector4(0,0,0,0)");
    lua_pushvector4(L,x/len,y/len,z/len,w/len);
    return 1;
  } else if (lua_gettop(L)==1 && lua_isquat(L,1)) {
    float w, x, y, z;
    float qlen;
    lua_checkquat(L, 1, &w, &x, &y, &z);
    qlen = sqrtf(w*w + x*x + y*y + z*z);
    if (qlen == 0)
        luaL_error(L, "Cannot normalise quat(0,0,0,0)");
    lua_pushquat(L,w/qlen,x/qlen,y/qlen,z/qlen);
    return 1;
  } else {
    return luaL_error(L, "Invalid arguments, try norm(v) or norm(q).");
  }
}
Пример #10
0
static int luaB_quat (lua_State *L) {
  if (lua_gettop(L)==4 && lua_isnumber(L,1) && lua_isnumber(L,2) && lua_isnumber(L,3) && lua_isnumber(L,4)) {
    float w,x,y,z;
    w = (float)lua_tonumber(L, 1);
    x = (float)lua_tonumber(L, 2);
    y = (float)lua_tonumber(L, 3);
    z = (float)lua_tonumber(L, 4);
    lua_pushquat(L, w,x,y,z);
    return 1;
  } else if (lua_gettop(L)==2 && lua_isnumber(L,1) && lua_isvector3(L,2)) {
    float angle,x,y,z,ha,s;
    angle = (float)lua_tonumber(L, 1);
    lua_checkvector3(L, 2, &x, &y, &z);
    ha = angle*(0.5f*PI/180.0f);
    s = sinf(ha);
    lua_pushquat(L, cosf(ha),s*x,s*y,s*z);
    return 1;
  } else if (lua_gettop(L)==2 && lua_isvector3(L,1) && lua_isvector3(L,2)) {
    float x1, y1, z1;
    float x2, y2, z2;
    float l1,l2,d;
    lua_checkvector3(L, 1, &x1, &y1, &z1);
    lua_checkvector3(L, 2, &x2, &y2, &z2);

    /* Based on Stan Melax's article in Game Programming Gems */
    l1 = sqrtf(x1*x1 + y1*y1 + z1*z1);
    l2 = sqrtf(x2*x2 + y2*y2 + z2*z2);
    x1/=l1; y1/=l1; z1/=l1; 
    x2/=l2; y2/=l2; z2/=l2; 

    d = dot3(x1,y1,z1, x2,y2,z2);

    /* If dot == 1, vectors are the same */
    if (d >= 1.0f) {
      lua_pushquat(L, 1,0,0,0);
      return 1;
    }

    if (d < (1e-6f - 1.0f)) {

      float ax, ay, az;
      float len2, len;

      cross3(1,0,0, x1,y1,z1, &ax, &ay, &az);
      len2 = ax*ax + ay*ay + az*az;
      if (len2 == 0) {
        cross3(0,1,0, x1,y1,z1, &ax, &ay, &az);
        len2 = ax*ax + ay*ay + az*az;
      }
      len = sqrtf(len2);
      ax/=len; ay/=len; az/=len; 
      lua_pushquat(L, 0,ax,ay,az);
      return 1;

    } else {

      float s = sqrtf((1+d)*2);
      float ax, ay, az;
      float qw, qlen;

      cross3(x1,y1,z1, x2,y2,z2, &ax, &ay, &az);
      ax/=s; ay/=s; az/=s; 
      qw = s*0.5f;
      qlen = sqrtf(qw*qw + ax*ax + ay*ay + az*az);
      lua_pushquat(L, qw/qlen,ax/qlen,ay/qlen,az/qlen);
      return 1;

    }

  } else {
    luaL_error(L, "Invalid params, try quat(n,n,n,n) quat(n,v3) quat(v3,v3)");
    return 0;
  }
}