Exemple #1
0
 /*
  * Idle Function - moves eyeposition
  */
void agvMove(void)
{

  switch (MoveMode)  {
    case FLYING:
      Ex += EyeMove*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
      Ey += EyeMove*sin(TORAD(EyeEl));
      Ez -= EyeMove*cos(TORAD(EyeAz))*cos(TORAD(EyeEl));
      break;

    case POLAR:
      EyeEl += ElSpin;
      EyeAz += AzSpin;
      if (ConstrainEl()) {  /* weird spin thing to make things look     */
        ElSpin = -ElSpin;      /* look better when you are kept from going */
                               /* upside down while spinning - Isn't great */
        if (fabs(ElSpin) > fabs(AzSpin))
          AzSpin = fabs(ElSpin) * ((AzSpin > 0) ? 1 : -1);
      }
      break;
    }

  if (AdjustingAzEl) {
    dAz *= SLOW_DAZ;
    dEl *= SLOW_DEL;
  }

  if (AllowIdle) {
    glutSetWindow(RedisplayWindow);
    glutPostRedisplay();
  }
}
Exemple #2
0
static void iterate( void ) {
	ALfloat orientation[]  = { 0.0f,  0.0f, -1.0f,
				   0.0f,  1.0f,  0.0f };
	ALfloat xaxis[]        = { 1.0f,  0.0f,  0.0f };
	ALfloat yaxis[]        = { 0.0f,  1.0f,  0.0f };
	ALfloat zaxis[]        = { 0.0f,  0.0f,  1.0f };
	ALfloat *at = orientation;
	ALfloat *up = &orientation[3];
	static ALint angle = 0;

	/*
	 * rotate up vector about at vector by angle degrees.
	 */
	_alRotatePointAboutAxis(TORAD(angle), up, at);

	fprintf(stderr, "orientation: \n\tAT(%f %f %f)\n\tUP(%f %f %f)\n",
		orientation[0], orientation[1], orientation[2],
		orientation[3], orientation[4], orientation[5]);

	fprintf(stderr, "angle = %d\n", angle);

	angle += 15; /* increment fifeteen degrees degree */

	alListenerfv(AL_ORIENTATION, orientation);

	micro_sleep(900000);
}
Exemple #3
0
  /*
   * I took the idea of tracking eye position in absolute
   * coords and direction looking in Polar form from denis
   */
void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el)
{
  float lookat[3], perp[3], up[3];

  lookat[0] = sin(TORAD(az))*cos(TORAD(el));
  lookat[1] = sin(TORAD(el));
  lookat[2] = -cos(TORAD(az))*cos(TORAD(el));
  normalize(lookat);
  perp[0] = lookat[2];
  perp[1] = 0;
  perp[2] = -lookat[0];
  normalize(perp);
  ncrossprod(lookat, perp, up);
  gluLookAt(x, y, z,
            x+lookat[0], y+lookat[1], z+lookat[2],
            up[0], up[1], up[2]);
}
Exemple #4
0
// adds all the shapes to a vector, that is used in the Update function.
void buildScene()
{
	if (shapes.size() == 0)
	{
		// a plane facing the camera, passing through point (0,0,1000)
		shapes.push_back(dynamic_cast<Shape*>(new Plane(Vec(0, 0, -1), -1000, Color(0, 30, 30))));

		// a sphere at (400,400,300), with radius 200
		shapes.push_back(dynamic_cast<Shape*>(new Sphere(Vec(400, 400, 300), 200, Color(100, 100, 0))));

		// two triangles 
		shapes.push_back(dynamic_cast<Shape*>(new Triangle({ 350, 100, 200 }, { 300,100,200 }, { 400,700, 30 }, { 200,0,0 })));
		shapes.push_back(dynamic_cast<Shape*>(new Triangle({ 100,300,0 }, { 150,300,0 }, { 100,100,0 }, { 0,0,255 })));
		shapes.push_back(dynamic_cast<Shape*>(new Triangle({ 150,300,0 }, { 150,100,0 }, { 100,100,0 }, { 0,255,255 })));


		float size = 20;
		Vec p0{ -1, 0, 0 }; Vec p1{ 1, 0, 0 }; Vec p2{ 0,2*size,0 };
		for (unsigned int i = 1; i <= 20; i++)
		{
			Vec off { size*2 * i, 700.0, 0.0 };
			p0.x = cosf(TORAD(i * (90/20.0f))) * size; p0.z = -sinf(TORAD(i * (90/20.0f))) * size;
			p1.x = -p0.x; p1.z = -p0.z;
			shapes.push_back(dynamic_cast<Shape*>(new Triangle(p0 + off, p1 + off, p2 + off, { 255,255,0 })));
		}
		
		// one OBB touching the sphere on the side
		// base
		Vec b1{ 1, 0, 0 };
		Vec b2{ 0, 1, 0 };
		Vec b3{ 0, 0, 1 };
		float angle{0.5};
		// rotate around Z the basis
		b1.x = cosf(angle); b1.y = -sinf(angle);
		b2.x = sinf(angle); b2.y = cosf(angle);
		shapes.push_back(dynamic_cast<Shape*>(new OBB(Vec(g_ToScreen->mScreenWidth/2, g_ToScreen->mScreenHeight/2, 100), b1, b2, b3, 50, 50, 50, { 0,255,0 })));
		// further rotate around X the basis
		float tempY = b1.y * cosf(angle) + b1.z * sinf(angle);
		b1.z = b1.y * -sinf(angle) + b1.z * cosf(angle);
		b1.y = tempY;
		tempY = b2.y * cosf(angle) + b2.z * sinf(angle);
		b2.z = b2.y * -sinf(angle) + b2.z * cosf(angle);
		b2.y = tempY;
		shapes.push_back(dynamic_cast<Shape*>(new OBB(Vec(200,600,400), b1,b2,b3, 100, 100, 100, {255,0,0})));
	}
}
Exemple #5
0
static void math_tan (void)
{
 double d;
 lua_Object o = lua_getparam (1);
 if (o == NULL)
 { lua_error ("too few arguments to function `tan'"); return; }
 if (!lua_isnumber(o))
 { lua_error ("incorrect arguments to function `tan'"); return; }
 d = lua_getnumber(o);
 lua_pushnumber (tan(TORAD(d)));
}
Exemple #6
0
 /*
  * change EyeEl and EyeAz and position when mouse is moved w/ button down
  */
void agvHandleMotion(int x, int y)
{
  int deltax = x - downx, deltay = y - downy;

  switch (downb) {
    case GLUT_LEFT_BUTTON:
      EyeEl  = downEl + EL_SENS * ((MoveMode == FLYING) ? -deltay : deltay);
      ConstrainEl();
      EyeAz  = downAz + AZ_SENS * deltax;
      dAz    = PREV_DAZ*dAz + CUR_DAZ*(lastAz - EyeAz);
      dEl    = PREV_DEL*dEl + CUR_DEL*(lastEl - EyeEl);
      lastAz = EyeAz;
      lastEl = EyeEl;
      break;
    case GLUT_MIDDLE_BUTTON:
        EyeDist = downDist + DIST_SENS*deltay;
        Ex = downEx - E_SENS*deltay*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
        Ey = downEy - E_SENS*deltay*sin(TORAD(EyeEl));
        Ez = downEz + E_SENS*deltay*cos(TORAD(EyeAz))*cos(TORAD(EyeEl));
      break;
  }
  glutPostRedisplay();
}
Exemple #7
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
    HMatrix R;
    EulerAngles sa, ra;
    const double *p_inangles;
    mxArray *outangles;
    const mwSize dims[]={3,1};
    
    /*get angles*/
    p_inangles=mxGetData(prhs[0]);
    sa.x=(float)p_inangles[0];
    sa.y=(float)p_inangles[1];
    sa.z=(float)p_inangles[2];
    
    /*convert angles from degrees to radians*/
    TORAD(sa.x);
    TORAD(sa.y);
    TORAD(sa.z);
    
    sa.w = EulOrdZYZr;
    Eul_ToHMatrix(sa, R);
    ra = Eul_FromHMatrix(R, EulOrdZXZr);
    
    /*convert angles from radians to degrees*/
    TODEG(ra.x);
    TODEG(ra.y);
    TODEG(ra.z);
    
    if ((plhs[0] = mxCreateNumericArray(2,dims,mxSINGLE_CLASS,mxREAL))==NULL) { mexErrMsgTxt("Memory allocation problem in tom_eulerconvert.\n"); }
    outangles = mxGetData(plhs[0]);
    ((float*)outangles)[0] = ra.x;
    ((float*)outangles)[1] = ra.y;
    ((float*)outangles)[2] = ra.z;
    /*printf("rotating angles = %10.3f %10.3f %10.3f\n", ra.x, ra.y, ra.z);*/
    
    
}
Exemple #8
0
  /*
   * when moving to flying we stay in the same spot, moving to polar we
   * reset since we have to be looking at the origin (though a pivot from
   * current position to look at origin might be cooler)
   */
void agvSwitchMoveMode(int move)
{
  switch (move) {
    case FLYING:
      if (MoveMode == FLYING) return;
      Ex    = -EyeDist*sin(TORAD(EyeAz))*cos(TORAD(EyeEl));
      Ey    =  EyeDist*sin(TORAD(EyeEl));
      Ez    =  EyeDist*(cos(TORAD(EyeAz))*cos(TORAD(EyeEl)));
      EyeAz =  EyeAz;
      EyeEl = -EyeEl;
      EyeMove = INIT_MOVE;
      break;
    case POLAR:
      EyeDist = INIT_DIST;
      EyeAz   = INIT_POLAR_AZ;
      EyeEl   = INIT_POLAR_EL;
      AzSpin  = INIT_AZ_SPIN;
      ElSpin  = INIT_EL_SPIN;
      break;
    }
  MoveMode = move;
  MoveOn(1);
  glutPostRedisplay();
}
Exemple #9
0
static void iterate( void ) {
	ALfloat orientation[]  = { 0.0f, 0.0f, -1.0f,
				   0.0f, 1.0f, 0.0f };
	static ALint angle = 0;

	/*
	 * rotate at vector about up vector by angle degrees.
	 */
	_alRotatePointAboutAxis(TORAD(angle), orientation, &orientation[3]);

	angle += 15; /* increment fifeteen degrees degree */

	fprintf(stderr, "orientation: \n\tAT(%f %f %f)\n\tUP(%f %f %f)\n",
		orientation[0], orientation[1], orientation[2],
		orientation[3], orientation[4], orientation[5]);

	alListenerfv(AL_ORIENTATION, orientation);

	micro_sleep(1500000);
}
Exemple #10
0
static void motion (int x, int y)
{
	if (!VManipulator::getCurrent())
		return;
	int dx = abs(x-g_x0);
	int dy = abs(y-g_y0);
	if ( dx > 1 || dy > 1) {
		if (g_state == 'r') {
			VVector v0 = map(g_x0, g_y0);
			VVector v1 = map(x, y);
			VVector r = Cross(v0, v1);
			VManipulator::getCurrent()->rotate(TORAD(2*asin(r.Length())),r.x,r.y,r.z);

		}
		else if (g_state == 's') {
			int vp[4];
			glGetIntegerv(GL_VIEWPORT,vp);
			float f = dx > dy ? (float)(x-g_x0) / vp[2] : (float) (-y+g_y0) / vp[3];
			VManipulator::getCurrent()->scale(1+f, 1+f, 1+f);
		}
		g_x0 = x; g_y0 = y;
		glutPostRedisplay();
	}
}
Exemple #11
0
static int math_cos (lua_State *L) {
  lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));
  return 1;
}
Exemple #12
0
static int math_tan (lua_State *L) {
  lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
  return 1;
}
Exemple #13
0
static void math_cos() {
	lua_pushnumber(cos(TORAD(luaL_check_number(1))));
}
Exemple #14
0
static void math_tan() {
	lua_pushnumber(tan(TORAD(luaL_check_number(1))));
}
Exemple #15
0
static void math_tan (void)
{
 double d = lua_check_number(1, "tan");
 lua_pushnumber (tan(TORAD(d)));
}
Exemple #16
0
void Character::Control(GLdouble FrameInterval)
{
	GLdouble step = WALK_SPEED;
	if(bSpecial[GLUT_KEY_SHIFT_L])
		step *= SPRINT_KOEF;

	if(bKeyboard['W']) {
		dVelocityX -= FrameInterval*AIR_ACCEL*step*sin(TORAD(dSpinY));
		dVelocityZ -= FrameInterval*AIR_ACCEL*step*cos(TORAD(dSpinY));
	}
	if(bKeyboard['S']) {
		dVelocityX += FrameInterval*AIR_ACCEL*step*sin(TORAD(dSpinY));
		dVelocityZ += FrameInterval*AIR_ACCEL*step*cos(TORAD(dSpinY));
	}
	if(bKeyboard['D']) {
		dVelocityX += FrameInterval*AIR_ACCEL*step*cos(TORAD(dSpinY));
		dVelocityZ -= FrameInterval*AIR_ACCEL*step*sin(TORAD(dSpinY));
	}
	if(bKeyboard['A']) {
		dVelocityX -= FrameInterval*AIR_ACCEL*step*cos(TORAD(dSpinY));
		dVelocityZ += FrameInterval*AIR_ACCEL*step*sin(TORAD(dSpinY));
	}
	if(bKeyboard['R']) {
		dVelocityY += FrameInterval*AIR_ACCEL*step;
	}
	if(bKeyboard['F']) {
		dVelocityY -= FrameInterval*AIR_ACCEL*step;
	}

	GLdouble ko = dVelocityX*dVelocityX + dVelocityZ*dVelocityZ;
	if(ko > WALK_SPEED*WALK_SPEED*SPRINT_KOEF*SPRINT_KOEF) {
		ko = pow(ko, 0.5);
		dVelocityX = dVelocityX*WALK_SPEED*SPRINT_KOEF/ko;
		dVelocityZ = dVelocityZ*WALK_SPEED*SPRINT_KOEF/ko;
	}

	if(bKeyboard[VK_SPACE]) {
	}
	
	if(bKeyboard['X']) {
		dVelocityX = 0;
		dVelocityY = 0;
		dVelocityZ = 0;
	}
	
	GLdouble yerr, xerr, zerr;
	GetPlane(&xerr, &yerr, &zerr);
	
	PosInWorld pos;
	if(zerr < xerr && zerr < yerr) {
		if((position.bz < centerPos.bz && position.cz == centerPos.cz) || position.cz < centerPos.cz) {
			pos = PosInWorld(0, 0, 0.5);
		} else {
			pos = PosInWorld(0, 0, -0.5);
		}
	} else if(xerr < zerr && xerr < yerr) {
		if((position.bx < centerPos.bx && position.cx == centerPos.cx) || position.cx < centerPos.cx) {
			pos = PosInWorld(0.5, 0, 0);
		} else {
			pos = PosInWorld(-0.5, 0, 0);
		}
	} else if(yerr < xerr && yerr < zerr) {
		if(position.by < centerPos.by) {
			pos = PosInWorld(0, 0.5, 0);
		} else {
			pos = PosInWorld(0, -0.5, 0);
		}
	}
	aimedBlock = BlockInWorld(centerPos + pos);
	freeBlock = BlockInWorld(centerPos + pos.inv());

	int num = 100;
	int sq = 100;
	int sqb2 = sq/2;

	if(bKeyboard['1']) {
		int i = 0;
		while(i < num) {
			if(wWorld.AddBlock(BlockInWorld(rand()%sq-sqb2, abs(rand()%sq-sqb2), rand()%sq-sqb2), rand()%14+1, true))
				i++;
		}
	}
	if(bKeyboard['2']) {
		int i = 0;
		while(i < num) {
			if(wWorld.RemoveBlock(BlockInWorld(rand()%sq-sqb2, rand()%sq-sqb2, rand()%sq-sqb2), true))
				i++;
		}
	}

	if(bKeyboard['3']) {
		for(BlockCoord i = -sqb2; i <= sqb2; i++) {
			for(BlockCoord j = -sqb2; j <= sqb2; j++) {
				for(BlockCoord k = -sqb2; k <= sqb2; k++) {
					wWorld.RemoveBlock(BlockInWorld(i, j, k), true);
				}
			}
		}
	}

	if(bKeyboard['4']) {
		wWorld.LoadChunk(0, 0);
		bKeyboard['4'] = false;
	}
	if(bKeyboard['5']) {
		wWorld.UnLoadChunk(0, 0);
		bKeyboard['5'] = false;
	}
	if(bKeyboard['6']) {
		for(int i = 0; i < 8; i++)
			for(int j = 0; j < 8; j++)
				wWorld.LoadChunk(i, j);
		bKeyboard['6'] = false;
	}
	if(bKeyboard['7']) {
		for(int i = 0; i < 8; i++)
			for(int j = 0; j < 8; j++)
				wWorld.UnLoadChunk(i, j);
		bKeyboard['7'] = false;
	}

	if(bKeyboard['0']) {
		static Param par = {0, 1, &wWorld};

		_beginthread(LoadNGenerate, 0, &par);

		WaitForSingleObject(wWorld.parget2, INFINITE);
		ResetEvent(wWorld.parget2);

		par.z++;
		bKeyboard['0'] = false;
	}
	
	if(bKeyboard['C']) {
		Chunk *chunk;
		int index;
		wWorld.FindBlock(aimedBlock, &chunk, &index);
		if ((chunk)&&(chunk->bBlocks[index].cMaterial == MAT_DIRT)) {
			chunk->bBlocks[index].bVisible ^= (1 << SNOWCOVERED);
		}
	}
	if(bKeyboard['V']) {
		Chunk *chunk;
		int index;
		wWorld.FindBlock(aimedBlock, &chunk, &index);
		if ((chunk)&&(chunk->bBlocks[index].cMaterial == MAT_DIRT)) {
			chunk->bBlocks[index].bVisible ^= (1 << GRASSCOVERED);
		}
	}
	if(bKeyboard['E']) {
		wWorld.RemoveBlock(aimedBlock, true);
	}
	if(bKeyboard['Q']) {
		wWorld.AddBlock(freeBlock, MAT_PUMPKIN_SHINE, true);
	}
	if(bKeyboard['O']) {
		wWorld.SaveChunks();
	}

	position = position + PosInWorld(FrameInterval*dVelocityX, FrameInterval*dVelocityY, FrameInterval*dVelocityZ);

	/*{
		signed short xx, yy, zz;
		GLdouble wx = gfPosX + gfVelX;
		GLdouble wy = gfPosY - PLAYER_HEIGHT + 0.1;
		GLdouble wz = gfPosZ;

		xx = floor(wx/TILE_SIZE + 0.5);
		zz = floor(wz/TILE_SIZE + 0.5);
		yy = floor(wy/TILE_SIZE);

		if((FindTile(xx, yy, zz) == NULL)&&(FindTile(xx, yy + 1, zz) == NULL))
			gfPosX += g_FrameInterval*gfVelX;
		else gfVelX = 0;
	}
	{
		signed short xx, yy, zz;
		GLdouble wx = gfPosX;
		GLdouble wy = gfPosY - PLAYER_HEIGHT + 0.1;
		GLdouble wz = gfPosZ + gfVelZ;

		xx = floor(wx/TILE_SIZE + 0.5);
		zz = floor(wz/TILE_SIZE + 0.5);
		yy = floor(wy/TILE_SIZE);

		if((FindTile(xx, yy, zz) == NULL)&&(FindTile(xx, yy + 1, zz) == NULL))
			gfPosZ += g_FrameInterval*gfVelZ;
		else gfVelZ = 0;
	}
	*/
	/*if(falling)
	{
		gfPosY -= g_FrameInterval*gfVelY;
		if(gfVelY < MAX_DOWNSTEP)
			gfVelY += g_FrameInterval*STEP_DOWNSTEP;
	}*/
	/*
	{
		signed short xx, yy, zz;
		GLdouble wx = gfPosX;
		GLdouble wy = gfPosY - PLAYER_HEIGHT;
		GLdouble wz = gfPosZ;

		xx = floor(wx/TILE_SIZE + 0.5);
		zz = floor(wz/TILE_SIZE + 0.5);
		yy = floor(wy/TILE_SIZE);

		if(FindTile(xx, yy, zz) == NULL) falling = true;
		else
		{
			gfVelY = 0;
			if(falling)
			{
				falling = false;
				gfPosY = (yy + 1)*TILE_SIZE + PLAYER_HEIGHT - 0.001;
			}
		}
	}

	if(!falling)
	{
		gfVelX = 0;
		gfVelZ = 0;
	}*/
	//falling = 1;

// 	if(dPositionX >= LOCATION_SIZE_XZ*TILE_SIZE) { dPositionX -= LOCATION_SIZE_XZ*TILE_SIZE; lnwPositionX++;}
// 	if(dPositionX < 0) { dPositionX += LOCATION_SIZE_XZ*TILE_SIZE; lnwPositionX--;}
// 	if(dPositionZ >= LOCATION_SIZE_XZ*TILE_SIZE) { dPositionZ -= LOCATION_SIZE_XZ*TILE_SIZE; lnwPositionZ++;}
// 	if(dPositionZ < 0) { dPositionZ += LOCATION_SIZE_XZ*TILE_SIZE; lnwPositionZ--;}

}
Exemple #17
0
static void math_sin (void)
{
 double d = lua_check_number(1, "sin");
 lua_pushnumber (sin(TORAD(d)));
}
Exemple #18
0
static void math_cos (void)
{
 double d = lua_check_number(1, "cos");
 lua_pushnumber (cos(TORAD(d)));
}
void icosaeder_vertices(real *xus)
{
    rh = sqrt(1.-2.*cos(TORAD(72.)))/(1.-cos(TORAD(72.)));
    rg = cos(TORAD(72.))/(1.-cos(TORAD(72.)));
    /* icosaeder vertices */
    xus[ 0] = 0.;                  xus[ 1] = 0.;                  xus[ 2] = 1.;
    xus[ 3] = rh*cos(TORAD(72.));  xus[ 4] = rh*sin(TORAD(72.));  xus[ 5] = rg;
    xus[ 6] = rh*cos(TORAD(144.)); xus[ 7] = rh*sin(TORAD(144.)); xus[ 8] = rg;
    xus[ 9] = rh*cos(TORAD(216.)); xus[10] = rh*sin(TORAD(216.)); xus[11] = rg;
    xus[12] = rh*cos(TORAD(288.)); xus[13] = rh*sin(TORAD(288.)); xus[14] = rg;
    xus[15] = rh;                  xus[16] = 0;                   xus[17] = rg;
    xus[18] = rh*cos(TORAD(36.));  xus[19] = rh*sin(TORAD(36.));  xus[20] = -rg;
    xus[21] = rh*cos(TORAD(108.)); xus[22] = rh*sin(TORAD(108.)); xus[23] = -rg;
    xus[24] = -rh;                 xus[25] = 0;                   xus[26] = -rg;
    xus[27] = rh*cos(TORAD(252.)); xus[28] = rh*sin(TORAD(252.)); xus[29] = -rg;
    xus[30] = rh*cos(TORAD(324.)); xus[31] = rh*sin(TORAD(324.)); xus[32] = -rg;
    xus[33] = 0.;                  xus[34] = 0.;                  xus[35] = -1.;
}
int ico_dot_arc(int densit)   /* densit...required dots per unit sphere */
{
    /* dot distribution on a unit sphere based on an icosaeder *
     * great circle average refining of icosahedral face       */

    int   i, j, k, tl, tl2, tn, tess;
    real  a, d, x, y, z, x2, y2, z2, x3, y3, z3;
    real  xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki,
          xjk, yjk, zjk, xkj, ykj, zkj;
    real *xus = NULL;

    /* calculate tessalation level */
    a     = sqrt((((real) densit)-2.)/10.);
    tess  = (int) ceil(a);
    n_dot = 10*tess*tess+2;
    if (n_dot < densit)
    {
        ERROR("ico_dot_arc: error in formula for tessalation level (%d->%d, %d)",
              tess, n_dot, densit);
    }

    snew(xus, 3*n_dot);
    xpunsp = xus;
    icosaeder_vertices(xus);

    if (tess > 1)
    {
        tn = 12;
        a  = rh*rh*2.*(1.-cos(TORAD(72.)));
        /* calculate tessalation of icosaeder edges */
        for (i = 0; i < 11; i++)
        {
            for (j = i+1; j < 12; j++)
            {
                x = xus[3*i]-xus[3*j];
                y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j];
                d = x*x+y*y+z*z;
                if (fabs(a-d) > DP_TOL)
                {
                    continue;
                }
                for (tl = 1; tl < tess; tl++)
                {
                    if (tn >= n_dot)
                    {
                        ERROR("ico_dot: tn exceeds dimension of xus");
                    }
                    divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                           xus[3*j], xus[1+3*j], xus[2+3*j],
                           tl, tess, &xus[3*tn], &xus[1+3*tn], &xus[2+3*tn]);
                    tn++;
                }
            }
        }
        /* calculate tessalation of icosaeder faces */
        for (i = 0; i < 10; i++)
        {
            for (j = i+1; j < 11; j++)
            {
                x = xus[3*i]-xus[3*j];
                y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j];
                d = x*x+y*y+z*z;
                if (fabs(a-d) > DP_TOL)
                {
                    continue;
                }

                for (k = j+1; k < 12; k++)
                {
                    x = xus[3*i]-xus[3*k];
                    y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k];
                    d = x*x+y*y+z*z;
                    if (fabs(a-d) > DP_TOL)
                    {
                        continue;
                    }
                    x = xus[3*j]-xus[3*k];
                    y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k];
                    d = x*x+y*y+z*z;
                    if (fabs(a-d) > DP_TOL)
                    {
                        continue;
                    }
                    for (tl = 1; tl < tess-1; tl++)
                    {
                        divarc(xus[3*j], xus[1+3*j], xus[2+3*j],
                               xus[3*i], xus[1+3*i], xus[2+3*i],
                               tl, tess, &xji, &yji, &zji);
                        divarc(xus[3*k], xus[1+3*k], xus[2+3*k],
                               xus[3*i], xus[1+3*i], xus[2+3*i],
                               tl, tess, &xki, &yki, &zki);

                        for (tl2 = 1; tl2 < tess-tl; tl2++)
                        {
                            divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                                   xus[3*j], xus[1+3*j], xus[2+3*j],
                                   tl2, tess, &xij, &yij, &zij);
                            divarc(xus[3*k], xus[1+3*k], xus[2+3*k],
                                   xus[3*j], xus[1+3*j], xus[2+3*j],
                                   tl2, tess, &xkj, &ykj, &zkj);
                            divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                                   xus[3*k], xus[1+3*k], xus[2+3*k],
                                   tess-tl-tl2, tess, &xik, &yik, &zik);
                            divarc(xus[3*j], xus[1+3*j], xus[2+3*j],
                                   xus[3*k], xus[1+3*k], xus[2+3*k],
                                   tess-tl-tl2, tess, &xjk, &yjk, &zjk);
                            if (tn >= n_dot)
                            {
                                ERROR("ico_dot: tn exceeds dimension of xus");
                            }
                            divarc(xki, yki, zki, xji, yji, zji, tl2, tess-tl,
                                   &x, &y, &z);
                            divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess-tl2,
                                   &x2, &y2, &z2);
                            divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl+tl2,
                                   &x3, &y3, &z3);
                            x           = x+x2+x3; y = y+y2+y3; z = z+z2+z3;
                            d           = sqrt(x*x+y*y+z*z);
                            xus[3*tn]   = x/d;
                            xus[1+3*tn] = y/d;
                            xus[2+3*tn] = z/d;
                            tn++;
                        } /* cycle tl2 */
                    }     /* cycle tl */
                }         /* cycle k */
            }             /* cycle j */
        }                 /* cycle i */
        if (n_dot != tn)
        {
            ERROR("ico_dot: n_dot(%d) and tn(%d) differ", n_dot, tn);
        }
    }   /* end of if (tess > 1) */

    return n_dot;
}                           /* end of routine ico_dot_arc */
Exemple #21
0
static void math_sin (void)
{
  lua_pushnumber(sin(TORAD(luaL_check_number(1))));
}
void HavokExport::makeHavokRigidBody(NiNodeRef parent, INode *ragdollParent, float scale) {

	this->scale = scale;

	Object *Obj = ragdollParent->GetObjectRef();

	Modifier* rbMod = nullptr;
	Modifier* shapeMod = nullptr;
	Modifier* constraintMod = nullptr;

	SimpleObject* havokTaperCapsule = nullptr;

	//get modifiers
	

	while (Obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
		IDerivedObject *DerObj = static_cast<IDerivedObject *> (Obj);
		const int nMods = DerObj->NumModifiers(); //it is really the last modifier on the stack, and not the total number of modifiers

		for (int i = 0; i < nMods; i++)
		{
			Modifier *Mod = DerObj->GetModifier(i);
			if (Mod->ClassID() == HK_RIGIDBODY_MODIFIER_CLASS_ID) {
				rbMod = Mod;
			}
			if (Mod->ClassID() == HK_SHAPE_MODIFIER_CLASS_ID) {
				shapeMod = Mod;
			}
			if (Mod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID || Mod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) {
				constraintMod = Mod;
			}
		}
		if (Obj->SuperClassID() == GEOMOBJECT_CLASS_ID) {
			havokTaperCapsule = (SimpleObject*)Obj;
		}
		Obj = DerObj->GetObjRef();
	}

	
	if (!rbMod) {
		throw exception(FormatText("No havok rigid body modifier found on %s", ragdollParent->GetName()));
	}
	if (!shapeMod) {
		throw exception(FormatText("No havok shape modifier found on %s", ragdollParent->GetName()));
	}

//	Object* taper = ragdollParent->GetObjectRef();
	IParamBlock2* taperParameters = Obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK);
	float radius;
	enum
	{
		// GENERAL PROPERTIES ROLLOUT
		PA_TAPEREDCAPSULE_OBJ_RADIUS = 0,
		PA_TAPEREDCAPSULE_OBJ_TAPER,
		PA_TAPEREDCAPSULE_OBJ_HEIGHT,
		PA_TAPEREDCAPSULE_OBJ_VERSION_INTERNAL,
	};
	taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, radius, FOREVER);
	

	int shapeType;
	if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) {
		shapeParameters->GetValue(PA_SHAPE_MOD_SHAPE_TYPE,0,shapeType,FOREVER);
	}

	//Havok Shape
	bhkShapeRef shape;

	if (shapeType == 2) {

		// Capsule
		bhkCapsuleShapeRef capsule = new bhkCapsuleShape();
		capsule->SetRadius(radius/scale);
		capsule->SetRadius1(radius/scale);
		capsule->SetRadius2(radius/scale);
		float length; 
		taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, length, FOREVER);
		//get the normal
		Matrix3 axis(true);
		ragdollParent->GetObjOffsetRot().MakeMatrix(axis);
		Point3 normalAx = axis.GetRow(2);
		//capsule center
		Point3 center = ragdollParent->GetObjOffsetPos();
		//min and max points
		Point3 pt1 = center - normalAx*(length/2);
		Point3 pt2 = center + normalAx*(length/2);

		capsule->SetFirstPoint(TOVECTOR3(pt1)/scale);
		capsule->SetSecondPoint(TOVECTOR3(pt2)/scale);
		capsule->SetMaterial(HAV_MAT_SKIN);

		shape = StaticCast<bhkShape>(capsule);
		
	}
	else {
		// Sphere
		//CalcBoundingSphere(node, tm.GetTrans(), radius, 0);

		bhkSphereShapeRef sphere = new bhkSphereShape();
		sphere->SetRadius(radius/scale);
		sphere->SetMaterial(HAV_MAT_SKIN);
		shape = StaticCast<bhkShape>(sphere);
	}

	bhkRigidBodyRef body;

	if (shape)
	{
		bhkBlendCollisionObjectRef blendObj = new bhkBlendCollisionObject();
		body = new bhkRigidBody();

		Matrix3 tm = ragdollParent->GetObjTMAfterWSM(0);
		
		//Calculate Object Offset Matrix
		Matrix3 otm(1);
		Point3 pos = ragdollParent->GetObjOffsetPos();
		otm.PreTranslate(pos);
		Quat quat = ragdollParent->GetObjOffsetRot();
		PreRotateMatrix(otm, quat);
		Matrix3 otmInvert = otm;
		otmInvert.Invert();

		//correct object tm
		Matrix3 tmbhk = otmInvert * tm;

		//set geometric parameters
		body->SetRotation(TOQUATXYZW(Quat(tmbhk).Invert()));
		body->SetTranslation(TOVECTOR4(tmbhk.GetTrans() / scale));
		body->SetCenter(TOVECTOR4(ragdollParent->GetObjOffsetPos())/scale);

		//set physics
		if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_RB_MOD_PBLOCK)) {
			//These are fundamental parameters

			int lyr = NP_DEFAULT_HVK_LAYER;
			int mtl = NP_DEFAULT_HVK_MATERIAL;
			int msys = NP_DEFAULT_HVK_MOTION_SYSTEM;
			int qtype = NP_DEFAULT_HVK_QUALITY_TYPE;
			float mass = NP_DEFAULT_HVK_MASS;
			float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING;
			float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING;
			float frict = NP_DEFAULT_HVK_FRICTION;
			float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY;
			float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY;
			float resti = NP_DEFAULT_HVK_RESTITUTION;
			float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH;
			Point3 InertiaTensor;


			rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_INERTIA_TENSOR, 0, InertiaTensor, FOREVER);


			rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER);

			rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER);

			rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER);
			rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER);

			body->SetMass(mass);
			body->SetRestitution(resti);
			body->SetFriction(frict);
			body->SetLinearDamping(lindamp);
			body->SetMaxLinearVelocity(maxlinvel);
			body->SetMaxAngularVelocity(maxangvel);
			body->SetPenetrationDepth(pendepth);
			InertiaMatrix im;
			im[0][0] = InertiaTensor[0];
			im[1][1] = InertiaTensor[1];
			im[2][2] = InertiaTensor[2];

			body->SetInertia(im);

			/*switch (qtype) {
			case QT_FIXED:
				body->SetQualityType(MO_QUAL_FIXED);
				break;
			case QT_KEYFRAMED:
				body->SetQualityType(MO_QUAL_KEYFRAMED);
				break;
			case QT_DEBRIS:
				body->SetQualityType(MO_QUAL_DEBRIS);
				break;
			case QT_MOVING:
				body->SetQualityType(MO_QUAL_MOVING);
				break;
			case QT_CRITICAL:
				body->SetQualityType(MO_QUAL_CRITICAL);
				break;
			case QT_BULLET:
				body->SetQualityType(MO_QUAL_BULLET);
				break;
			case QT_KEYFRAMED_REPORTING:
				body->SetQualityType(MO_QUAL_KEYFRAMED_REPORT);
				break;
			}*/

			body->SetSkyrimLayer(SkyrimLayer::SKYL_BIPED);
			body->SetSkyrimLayerCopy(SkyrimLayer::SKYL_BIPED);

			body->SetMotionSystem(MotionSystem::MO_SYS_BOX);
			body->SetDeactivatorType(DeactivatorType::DEACTIVATOR_NEVER);
			body->SetSolverDeactivation(SolverDeactivation::SOLVER_DEACTIVATION_LOW);
			body->SetQualityType(MO_QUAL_FIXED);

		}
		
		if (constraintMod && ragdollParent->GetParentNode() && parent->GetParent()) {
			if (constraintMod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID) {
				bhkRagdollConstraintRef ragdollConstraint = new bhkRagdollConstraint();
				
				//entities
				ragdollConstraint->AddEntity(body);
				NiNodeRef parentRef = parent->GetParent();
				bhkRigidBodyRef nifParentRigidBody;
				while (parentRef) {
					if (parentRef->GetCollisionObject()) {
						nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody());
						break;
					}
					parentRef = parentRef->GetParent();
				}
				if (!nifParentRigidBody)
					throw exception(FormatText("Unable to find NIF constraint parent for ragdoll node %s", ragdollParent->GetName()));
				ragdollConstraint->AddEntity(nifParentRigidBody);

				RagdollDescriptor desc;
				//parameters
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					Point3 pivotA;
					Matrix3 parentRotation;
					Point3 pivotB;
					Matrix3 childRotation;
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, pivotB, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, pivotA, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER);
					
					desc.pivotA = TOVECTOR4(pivotA);
					desc.pivotB = TOVECTOR4(pivotB);
					desc.planeA = TOVECTOR4(parentRotation.GetRow(0));
					desc.motorA = TOVECTOR4(parentRotation.GetRow(1));
					desc.twistA = TOVECTOR4(parentRotation.GetRow(2));
					desc.planeB = TOVECTOR4(childRotation.GetRow(0));
					desc.motorB = TOVECTOR4(childRotation.GetRow(1));
					desc.twistB = TOVECTOR4(childRotation.GetRow(2));
					
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
					float coneMaxAngle;
					float planeMinAngle;
					float planeMaxAngle;
					float coneMinAngle;
					float twistMinAngle;
					float maxFriction;

					constraintParameters->GetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, coneMaxAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, planeMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, planeMaxAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, coneMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, twistMinAngle, FOREVER);
					constraintParameters->GetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER);

					desc.coneMaxAngle = TORAD(coneMaxAngle);
					desc.planeMinAngle = TORAD(planeMinAngle);
					desc.planeMaxAngle = TORAD(planeMaxAngle);
					desc.coneMaxAngle = TORAD(coneMinAngle);
					desc.twistMinAngle = TORAD(twistMinAngle);
					desc.maxFriction = maxFriction;


				}
				ragdollConstraint->SetRagdoll(desc);
				body->AddConstraint(ragdollConstraint);
			}
			else if (constraintMod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) {
				bhkLimitedHingeConstraintRef limitedHingeConstraint = new bhkLimitedHingeConstraint();

				//entities
				limitedHingeConstraint->AddEntity(body);
				NiNodeRef parentRef = parent->GetParent();
				bhkRigidBodyRef nifParentRigidBody;
				while (parentRef) {
					if (parentRef->GetCollisionObject()) {
						nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody());
						break;
					}
					parentRef = parentRef->GetParent();
				}
				if (!nifParentRigidBody)
					throw exception(FormatText("Unable to find NIF constraint parent for limited hinge node %s", ragdollParent->GetName()));
				limitedHingeConstraint->AddEntity(nifParentRigidBody);

				LimitedHingeDescriptor lh;

				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					Matrix3 parentRotation;
					Matrix3 childRotation;
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER);
					constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER);

					lh.perp2AxleInA1 = TOVECTOR4(parentRotation.GetRow(0));
					lh.perp2AxleInA2 = TOVECTOR4(parentRotation.GetRow(1));
					lh.axleA = TOVECTOR4(parentRotation.GetRow(2));
					lh.perp2AxleInB1 = TOVECTOR4(childRotation.GetRow(0));
					lh.perp2AxleInB2 = TOVECTOR4(childRotation.GetRow(1));
					lh.axleB = TOVECTOR4(childRotation.GetRow(2));
					
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
					float minAngle;
					float maxAngle;
					float maxFriction;

					constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MIN, 0, minAngle, FOREVER);
					constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MAX, 0, maxAngle, FOREVER);
					constraintParameters->GetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER);
					//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);

					lh.minAngle = TORAD(minAngle);
					lh.maxAngle = TORAD(maxAngle);
					lh.maxAngle = maxFriction;

				}
				limitedHingeConstraint->SetLimitedHinge(lh);
				body->AddConstraint(limitedHingeConstraint);
			}
		}


		//InitializeRigidBody(body, node);
		body->SetShape(shape);
		blendObj->SetBody(StaticCast<NiObject>(body));
		parent->SetCollisionObject(StaticCast<NiCollisionObject>(blendObj));
	}

	////rigid body parameters
	//	// get data from node
	//int lyr = NP_DEFAULT_HVK_LAYER;
	//int mtl = NP_DEFAULT_HVK_MATERIAL;
	//int msys = NP_DEFAULT_HVK_MOTION_SYSTEM;
	//int qtype = NP_DEFAULT_HVK_QUALITY_TYPE;
	//float mass = NP_DEFAULT_HVK_MASS;
	//float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING;
	//float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING;
	//float frict = NP_DEFAULT_HVK_FRICTION;
	//float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY;
	//float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY;
	//float resti = NP_DEFAULT_HVK_RESTITUTION;
	//float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH;
	//BOOL transenable = TRUE;

	//if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK))
	//{
	//	//These are fundamental parameters
	//	rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER);
	//	rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER);

	//	rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER);


	//	switch (qtype) {
	//	case MO_QUAL_INVALID:
	//		break;
	//	case QT_FIXED:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, MO_QUAL_FIXED, 0);
	//		break;
	//	case MO_QUAL_KEYFRAMED:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED, 0);
	//		break;
	//	case MO_QUAL_DEBRIS:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_DEBRIS, 0);
	//		break;
	//	case MO_QUAL_MOVING:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_MOVING, 0);
	//		break;
	//	case MO_QUAL_CRITICAL:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_CRITICAL, 0);
	//		break;
	//	case MO_QUAL_BULLET:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_BULLET, 0);
	//		break;
	//	case MO_QUAL_USER:
	//		break;
	//	case MO_QUAL_CHARACTER:
	//		break;
	//	case MO_QUAL_KEYFRAMED_REPORT:
	//		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED_REPORTING, 0);
	//		break;
	//	}

	//	// setup body
	//	bhkRigidBodyRef body = transenable ? new bhkRigidBodyT() : new bhkRigidBody();

	//	OblivionLayer obv_layer; SkyrimLayer sky_layer;
	//	GetHavokLayersFromIndex(lyr, (int*)&obv_layer, (int*)&sky_layer);
	//	body->SetLayer(obv_layer);
	//	body->SetLayerCopy(obv_layer);
	//	body->SetSkyrimLayer(sky_layer);

	//	body->SetMotionSystem(MotionSystem(msys));
	//	body->SetQualityType(MotionQuality(qtype));
	//	body->SetMass(mass);
	//	body->SetLinearDamping(lindamp);
	//	body->SetAngularDamping(angdamp);
	//	body->SetFriction(frict);
	//	body->SetRestitution(resti);
	//	body->SetMaxLinearVelocity(maxlinvel);
	//	body->SetMaxAngularVelocity(maxangvel);
	//	body->SetPenetrationDepth(pendepth);
	//	body->SetCenter(center);
	//	QuaternionXYZW q; q.x = q.y = q.z = 0; q.w = 1.0f;
	//	body->SetRotation(q);
	//}
}
int ico_dot_dod(int densit) /* densit...required dots per unit sphere */
{
    /* dot distribution on a unit sphere based on an icosaeder *
     * great circle average refining of icosahedral face       */

    int   i, j, k, tl, tl2, tn, tess, j1, j2;
    real  a, d, x, y, z, x2, y2, z2, x3, y3, z3, ai_d, adod;
    real  xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki,
          xjk, yjk, zjk, xkj, ykj, zkj;
    real *xus = NULL;
    /* calculate tesselation level */
    a     = sqrt((((real) densit)-2.)/30.);
    tess  = max((int) ceil(a), 1);
    n_dot = 30*tess*tess+2;
    if (n_dot < densit)
    {
        ERROR("ico_dot_dod: error in formula for tessalation level (%d->%d, %d)",
              tess, n_dot, densit);
    }

    snew(xus, 3*n_dot);
    xpunsp = xus;
    icosaeder_vertices(xus);

    tn = 12;
    /* square of the edge of an icosaeder */
    a = rh*rh*2.*(1.-cos(TORAD(72.)));
    /* dodecaeder vertices */
    for (i = 0; i < 10; i++)
    {
        for (j = i+1; j < 11; j++)
        {
            x = xus[3*i]-xus[3*j];
            y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j];
            d = x*x+y*y+z*z;
            if (fabs(a-d) > DP_TOL)
            {
                continue;
            }
            for (k = j+1; k < 12; k++)
            {
                x = xus[3*i]-xus[3*k];
                y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k];
                d = x*x+y*y+z*z;
                if (fabs(a-d) > DP_TOL)
                {
                    continue;
                }
                x = xus[3*j]-xus[3*k];
                y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k];
                d = x*x+y*y+z*z;
                if (fabs(a-d) > DP_TOL)
                {
                    continue;
                }
                x         = xus[  3*i]+xus[  3*j]+xus[  3*k];
                y         = xus[1+3*i]+xus[1+3*j]+xus[1+3*k];
                z         = xus[2+3*i]+xus[2+3*j]+xus[2+3*k];
                d         = sqrt(x*x+y*y+z*z);
                xus[3*tn] = x/d; xus[1+3*tn] = y/d; xus[2+3*tn] = z/d;
                tn++;
            }
        }
    }

    if (tess > 1)
    {
        tn = 32;
        /* square of the edge of an dodecaeder */
        adod = 4.*(cos(TORAD(108.))-cos(TORAD(120.)))/(1.-cos(TORAD(120.)));
        /* square of the distance of two adjacent vertices of ico- and dodecaeder */
        ai_d = 2.*(1.-sqrt(1.-a/3.));

        /* calculate tessalation of mixed edges */
        for (i = 0; i < 31; i++)
        {
            j1 = 12; j2 = 32; a = ai_d;
            if (i >= 12)
            {
                j1 = i+1; a = adod;
            }
            for (j = j1; j < j2; j++)
            {
                x = xus[3*i]-xus[3*j];
                y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j];
                d = x*x+y*y+z*z;
                if (fabs(a-d) > DP_TOL)
                {
                    continue;
                }
                for (tl = 1; tl < tess; tl++)
                {
                    if (tn >= n_dot)
                    {
                        ERROR("ico_dot: tn exceeds dimension of xus");
                    }
                    divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                           xus[3*j], xus[1+3*j], xus[2+3*j],
                           tl, tess, &xus[3*tn], &xus[1+3*tn], &xus[2+3*tn]);
                    tn++;
                }
            }
        }
        /* calculate tessalation of pentakisdodecahedron faces */
        for (i = 0; i < 12; i++)
        {
            for (j = 12; j < 31; j++)
            {
                x = xus[3*i]-xus[3*j];
                y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j];
                d = x*x+y*y+z*z;
                if (fabs(ai_d-d) > DP_TOL)
                {
                    continue;
                }

                for (k = j+1; k < 32; k++)
                {
                    x = xus[3*i]-xus[3*k];
                    y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k];
                    d = x*x+y*y+z*z;
                    if (fabs(ai_d-d) > DP_TOL)
                    {
                        continue;
                    }
                    x = xus[3*j]-xus[3*k];
                    y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k];
                    d = x*x+y*y+z*z;
                    if (fabs(adod-d) > DP_TOL)
                    {
                        continue;
                    }
                    for (tl = 1; tl < tess-1; tl++)
                    {
                        divarc(xus[3*j], xus[1+3*j], xus[2+3*j],
                               xus[3*i], xus[1+3*i], xus[2+3*i],
                               tl, tess, &xji, &yji, &zji);
                        divarc(xus[3*k], xus[1+3*k], xus[2+3*k],
                               xus[3*i], xus[1+3*i], xus[2+3*i],
                               tl, tess, &xki, &yki, &zki);

                        for (tl2 = 1; tl2 < tess-tl; tl2++)
                        {
                            divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                                   xus[3*j], xus[1+3*j], xus[2+3*j],
                                   tl2, tess, &xij, &yij, &zij);
                            divarc(xus[3*k], xus[1+3*k], xus[2+3*k],
                                   xus[3*j], xus[1+3*j], xus[2+3*j],
                                   tl2, tess, &xkj, &ykj, &zkj);
                            divarc(xus[3*i], xus[1+3*i], xus[2+3*i],
                                   xus[3*k], xus[1+3*k], xus[2+3*k],
                                   tess-tl-tl2, tess, &xik, &yik, &zik);
                            divarc(xus[3*j], xus[1+3*j], xus[2+3*j],
                                   xus[3*k], xus[1+3*k], xus[2+3*k],
                                   tess-tl-tl2, tess, &xjk, &yjk, &zjk);
                            if (tn >= n_dot)
                            {
                                ERROR("ico_dot: tn exceeds dimension of xus");
                            }
                            divarc(xki, yki, zki, xji, yji, zji, tl2, tess-tl,
                                   &x, &y, &z);
                            divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess-tl2,
                                   &x2, &y2, &z2);
                            divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl+tl2,
                                   &x3, &y3, &z3);
                            x           = x+x2+x3; y = y+y2+y3; z = z+z2+z3;
                            d           = sqrt(x*x+y*y+z*z);
                            xus[3*tn]   = x/d;
                            xus[1+3*tn] = y/d;
                            xus[2+3*tn] = z/d;
                            tn++;
                        } /* cycle tl2 */
                    }     /* cycle tl */
                }         /* cycle k */
            }             /* cycle j */
        }                 /* cycle i */
        if (n_dot != tn)
        {
            ERROR("ico_dot: n_dot(%d) and tn(%d) differ", n_dot, tn);
        }
    }   /* end of if (tess > 1) */

    return n_dot;
}       /* end of routine ico_dot_dod */