Example #1
0
static int
test_angle (const vec3_t angles)
{
	int         i;
	quat_t      rotation, r;
	vec3_t      scale, shear;
	mat3_t      mat;

	AngleQuat (angles, rotation);
	QuatToMatrix (rotation, mat, 0, 1);
	Mat3Decompose (mat, r, shear, scale);
	for (i = 0; i < 4; i++)
		if (!compare (rotation[i], r[i]))
			goto negate;
	return 1;
negate:
	// Mat3Decompose always sets the rotation quaternion's scalar to +ve
	// but AngleQuat might produce a -ve scalar.
	QuatNegate (r, r);
	for (i = 0; i < 4; i++)
		if (!compare (rotation[i], r[i]))
			goto fail;

	return 1;
fail:
	printf ("\n\n(%g %g %g)\n", VectorExpand (angles));
	printf ("  [%g %g %g %g]\n", QuatExpand (rotation));
	printf ("  [%g %g %g %g] [%g %g %g] [%g %g %g]\n",
			QuatExpand (r), VectorExpand (scale), VectorExpand (shear));
	return 0;
}
void Orientation_Widget::setQuat( QQuaternion q )
{
	quat = q;
	QMatrix3x3 m = QuatToMatrix( quat );
	mat = QMatrix4x4(m);

	update();
}
void Orientation_Widget::setQuat2( QQuaternion q )
{
	quat2 = q;
	QMatrix3x3 m = QuatToMatrix( quat2 );
	mat2 = QMatrix4x4(m);
	bQuat2Valid = true;

	update();
}
Example #4
0
bool BOTAI_WillHomingMissileHit(VECTOR * MyPos)
{
	float Cos;
	float Angle;
	VECTOR DirVector;
	VECTOR TmpVec;
	QUATLERP qlerp;
	SECONDARYWEAPONBULLET MissCopy = SecBulls[ HomingMissile ];

	// direction vector from missile to me
	DirVector.x = MyPos->x - MissCopy.Pos.x;
	DirVector.y = MyPos->y - MissCopy.Pos.y;
	DirVector.z = MyPos->z - MissCopy.Pos.z;
	NormaliseVector( &DirVector );

	// angle difference between the missile's current vector and wanted vector
	Cos = DotProduct( &DirVector, &MissCopy.DirVector );

	// set the parameters to perform a linear interpolation on two quaternions
	QuatFrom2Vectors( &qlerp.end, &Forward, &DirVector );
	qlerp.start	= MissCopy.DirQuat;				
	qlerp.crnt	= &MissCopy.DirQuat;	
	qlerp.dir	= QuatDotProduct( &qlerp.start, &qlerp.end );

	// bound angle difference
	if( Cos < -1.0F ) Cos = -1.0F;
	else if ( Cos > 1.0F ) Cos = 1.0F;

	// get angle difference in radians
	Angle = (float) acos( Cos );

	// calculate the amount of angle to turn 
	if( Angle ) qlerp.time = ( ( D2R( MissCopy.TurnSpeed ) * framelag ) / Angle );
	else qlerp.time = 1.0F;
	if( qlerp.time > 1.0F ) qlerp.time = 1.0F;

	// perform quat interpolation
	QuatInterpolate( &qlerp );
	QuatToMatrix( &MissCopy.DirQuat, &MissCopy.Mat );
	ApplyMatrix( &MissCopy.Mat, &Forward, &MissCopy.DirVector );
	ApplyMatrix( &MissCopy.Mat, &SlideUp, &MissCopy.UpVector );

	// will missile hit?
	if(RaytoSphere2(MyPos, SHIP_RADIUS, &MissCopy.Pos, &MissCopy.DirVector, &TmpVec, &TmpVec ))
	{
		DebugPrintf("homing missile will hit\n");
		return true;
	}
	else
	{
		DebugPrintf("safe from homing missile\n");
		return false;
	}
}
Example #5
0
/*-------------------------------------------------------------------
    Procedure   :       Create Quat from dir vector and up vector
    Input       :       VECTOR  *   Direction Vector
                :       VECTOR  *   Up Vector
                :       QUAT    *   Destin Quaternion
    Output      :       Nothing
-------------------------------------------------------------------*/
void QuatFromDirAndUp( VECTOR * Dir, VECTOR * Up, QUAT * Quat )
{
    MATRIX      TempMat;
    VECTOR      TempUp;
    QUAT        RotQuat;

    QuatFrom2Vectors( Quat, &Forward, Dir );
    QuatToMatrix( Quat, &TempMat );
    ApplyMatrix( &TempMat, &SlideUp, &TempUp );
    QuatFrom2Vectors( &RotQuat, &TempUp, Up );
    QuatMultiply( &RotQuat, Quat, Quat );
}
Example #6
0
void _GetMatrix(Animation* animation, double time, double m[4][4])
{
   Animation* a = (Animation*) animation;
   
   /* m = translation * rotation * scale */
   
   /* Rotation. */
   if(a->rotations)
   {
      double drot[4];
      _GetRotation(a, time, drot);
      
      Rotation3 RR;
      RR.x = drot[0];
      RR.y = drot[1];
      RR.z = drot[2];
      RR.angle = drot[3];
      
      Quaternion q;
      FromAngleAxis(&q, RR.angle, RR.x, RR.y, RR.z);
      QuatToMatrix(&q, m); /* Also sets bottom row to 0 0 0 1 */
   }
   else
   {
      m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
      m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
      m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
      m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
   }

   /* Concatenate with scaling. */
   if(a->scales)
   {
      double S[3];
      _GetScale(a, time, S);

      m[0][0] *= S[0]; m[0][1] *= S[1]; m[0][2] *= S[2];
      m[1][0] *= S[0]; m[1][1] *= S[1]; m[1][2] *= S[2];
      m[2][0] *= S[0]; m[2][1] *= S[1]; m[2][2] *= S[2];
   }

   /* Translation. */
   if(a->translations)  
   {
      double P[3];
      _GetTranslation(a, time, P);
      
      m[0][3] = P[0];
      m[1][3] = P[1];
      m[2][3] = P[2];
   }
}
Example #7
0
/*===================================================================
	Procedure	:	Check if im in an Active Teleport....
	Input		:	void
	Output		:	true/false
===================================================================*/
bool TeleportsAreaCheck( VECTOR * NewPos , VECTOR * OldPos ,u_int16_t Group, OBJECT *obj )
{
	TELEPORT * TPpnt;
	TELEPORT * newTPpnt;

	TPpnt = TeleportsGroupLink[Group];
	
	while( TPpnt )
	{
		if( TPpnt->Status == TELEPORTACTIVE )
		{
			TeleportsZoneCheck( OldPos , NewPos , TPpnt );
			if( Entry )
			{

				PlaySfx( SFX_Teleport, 1.0F );

//				StartShipScreenShake( 10.0F );
				
				
				// Were in the Zone....
				newTPpnt = Teleports;
				newTPpnt += TPpnt->Links[Random_Range(TPpnt->num_links)];
				obj->Group = newTPpnt->Group;
				obj->Pos = newTPpnt->Pos;
#if TELEPORTS_VERSION_NUMBER >= 2
				QuatFromDirAndUp( &newTPpnt->Dir, &newTPpnt->Up, &obj->Quat);
				QuatToMatrix( &obj->Quat, &obj->Mat );
#endif
				return true;
			}
		}
		TPpnt = TPpnt->NextInGroup;
	}
	return false;
}
Example #8
0
int SearObject::init(const std::string &file_name) {
  assert(m_initialised == false);
 
  std::string object;
  if (m_config.readFromFile(file_name)) {
    if (m_config.findItem(SECTION_model, KEY_filename)) {
      object = (std::string)m_config.getItem(SECTION_model, KEY_filename);
    } else {
      fprintf(stderr, "[SearObject] Error: No SearObject filename specified.\n");
      return 1;
    }
  } else {
    fprintf(stderr, "[SearObject] Error reading %s as varconf file. Trying as SearObject file.\n", file_name.c_str());
    object = file_name;
  }

  System::instance()->getFileHandler()->getFilePath(object);

  // Load SearObject file
  if (load(object)) {
    //  Error loading object
    fprintf(stderr, "[SearObject] Error loading SearObject %s\n", object.c_str());
    m_static_objects.clear();
    return 1;
  }


 // Initialise transform matrix
  float matrix[4][4];
  for (int j = 0; j < 4; ++j) {
    for (int i = 0; i < 4; ++i) {
      if (i == j) matrix[j][i] = 1.0f;
      else matrix[j][i] = 0.0f;
    }
  }
  bool do_transform = false;
  if (m_config.findItem(SECTION_model, KEY_rotation)) {
    const std::string &str=(std::string)m_config.getItem(SECTION_model, KEY_rotation);
    float w,x,y,z;
    sscanf(str.c_str(), "%f;%f;%f;%f", &w, &x, &y, &z);
    WFMath::Quaternion q(w,x,y,z);
    QuatToMatrix(q, matrix);
    do_transform = true;
  }
  if (m_config.findItem(SECTION_model, KEY_scale)) {
    double s = (double)m_config.getItem(SECTION_model, KEY_scale);
    for (int i = 0; i < 4; ++i) matrix[i][i] *= s;
    do_transform = true;
  }
  if (do_transform) {
    transform_object(m_static_objects, matrix);
  }

  bool ignore_minus_z = false;

  Scaling scale = SCALE_NONE;
  Alignment align = ALIGN_NONE;
  bool process_model = false;

  if (m_config.findItem(SECTION_model, KEY_ignore_minus_z)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_ignore_minus_z)) {
      process_model = true;
      ignore_minus_z = true;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_z_align)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_z_align)) {
      process_model = true;
      align = ALIGN_Z;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_align_mass)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_align_mass)) {
      process_model = true;
      align = ALIGN_CENTRE_MASS;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_align_bbox_hc)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_align_bbox_hc)) {
      process_model = true;
      align = ALIGN_BBOX_HC;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_align_bbox_lc)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_align_bbox_lc)) {
      process_model = true;
      align = ALIGN_BBOX_LC;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_align_extent)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_align_extent)) {
      process_model = true;
      align = ALIGN_CENTRE_EXTENT;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_scale_isotropic)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic)) {
      process_model = true;
      scale = SCALE_ISOTROPIC;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_x)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_x)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Z;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_y)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_y)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Y;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_z)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_z)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Z;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_scale_anisotropic)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_anisotropic)) {
      process_model = true;
      scale = SCALE_ANISOTROPIC;
    }
  }
  
  if (process_model == true) {
    scale_object(m_static_objects, scale, align, ignore_minus_z);
  }


  contextCreated();

  m_initialised = true;

  return 0;
}
Example #9
0
int LibModelFile::init(const std::string &filename) {
  assert(m_initialised == false);

  std::string object;
  if (m_config.readFromFile(filename)) {
    if (m_config.findItem(SECTION_model, KEY_filename)) {
      object = (std::string)m_config.getItem(SECTION_model, KEY_filename);
    } else {
      fprintf(stderr, "[LibModelFile] Error: No md3 filename specified.\n");
      return 1;
    }
  } else {
    fprintf(stderr, "[LibModelFile] Error reading %s as varconf file. Trying as .md3 file.\n",
            filename.c_str());
    object = filename;
  }
  // Initialise transform matrix
  float matrix[4][4];
  for (int j = 0; j < 4; ++j) {
    for (int i = 0; i < 4; ++i) {
      if (i == j) matrix[j][i] = 1.0f;
      else matrix[j][i] = 0.0f;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_rotation)) {
    const std::string &str=(std::string)m_config.getItem(SECTION_model, KEY_rotation);
    float w,x,y,z;
    sscanf(str.c_str(), "%f;%f;%f;%f", &w, &x, &y, &z);
    WFMath::Quaternion q(w,x,y,z);
    QuatToMatrix(q, matrix);
  }
  if (m_config.findItem(SECTION_model, KEY_scale)) {
    double s = (double)m_config.getItem(SECTION_model, KEY_scale);
    for (int i = 0; i < 4; ++i) matrix[i][i] *= s;
  }

  System::instance()->getFileHandler()->getFilePath(object);

  // Load md3 file
//  if (debug) printf("[LibModelFile] Loading: %s\n", object.c_str());

  libmd3_file *modelFile = libmd3_file_load(object.c_str());
  if (!modelFile) {
    fprintf(stderr, "[LibModelFile] Error loading %s file\n", object.c_str());
    return 1;
  }

  for (int i = 0; i < modelFile->header->mesh_count; ++i) {
    libmd3_unpack_normals(&modelFile->meshes[i]);
  }

  // Get mesh data
  libmd3_mesh *meshp = modelFile->meshes;
  for (int i = 0; i < modelFile->header->mesh_count; ++i, ++meshp) {
    StaticObject* so = new StaticObject();
    so->init();

    // Get Texture data from Mesh
    int texture_id = NO_TEXTURE_ID;
    int texture_mask_id = NO_TEXTURE_ID;
    if (meshp->mesh_header->skin_count != 0) {
      std::string name = (const char*)(meshp->skins[0].name);
      m_config.clean(name);

      // Check for texture name overrides in vconf file
      // Backwards compatibility.
      if (m_config.findItem(name, KEY_filename)) {
        name = (std::string)m_config.getItem(name, KEY_filename);
      }
      // Check for texture name overrides in vconf file
      // New method
      if (m_config.findItem(name, KEY_texture_map_0)) {
        name = (std::string)m_config.getItem(name, KEY_texture_map_0);
      }
      // Request Texture ID
      texture_id = RenderSystem::getInstance().requestTexture(name);
      texture_mask_id = RenderSystem::getInstance().requestTexture(name, true);

      float m[4];
      if (m_config.findItem(name, KEY_ambient)) {
        const std::string &str = (std::string)m_config.getItem(name, KEY_ambient);
        sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]);
        so->setAmbient(m); 
      }
      if (m_config.findItem(name, KEY_diffuse)) {
        const std::string &str = (std::string)m_config.getItem(name, KEY_diffuse);
        sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]);
        so->setDiffuse(m); 
      }
      if (m_config.findItem(name, KEY_specular)) {
        const std::string &str = (std::string)m_config.getItem(name, KEY_specular);
        sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]);
        so->setSpecular(m); 
      }
      if (m_config.findItem(name, KEY_emission)) {
        const std::string &str = (std::string)m_config.getItem(name, KEY_emission);
        sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]);
        so->setEmission(m); 
      }
      if (m_config.findItem(name, KEY_shininess)) {
        so->setShininess((double)m_config.getItem(name, KEY_shininess));
      }
      
    }
    // Set the transform
    so->getMatrix().setMatrix(matrix);
    // Set the textures
    so->setTexture(0, texture_id, texture_mask_id);
    so->setNumPoints(meshp->mesh_header->vertex_count);
    so->setNumFaces(meshp->mesh_header->triangle_count);

    // Copy data into array.
    so->createVertexData(meshp->mesh_header->vertex_count * 3);
    float *ptr = so->getVertexDataPtr();
    for (int i = 0; i < meshp->mesh_header->vertex_count * 3; ++i) {
      ptr[i] = default_scale * (float)meshp->vertices[i];
    }  
 
    so->copyTextureData(meshp->texcoords, meshp->mesh_header->vertex_count * 2);
    so->copyNormalData(meshp->normals, meshp->mesh_header->vertex_count * 3);

    so->copyIndices(meshp->triangles, meshp->mesh_header->triangle_count * 3);

    m_static_objects.push_back(so);
  }

  libmd3_file_free(modelFile);


  bool ignore_minus_z = false;

  Scaling scale = SCALE_NONE;
  Alignment align = ALIGN_NONE;
  bool process_model = false;

  if (m_config.findItem(SECTION_model, KEY_ignore_minus_z)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_ignore_minus_z)) {
      process_model = true;
      ignore_minus_z = true;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_z_align)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_z_align)) {
      process_model = true;
      align = ALIGN_Z;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_scale_isotropic)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic)) {
      process_model = true;
      scale = SCALE_ISOTROPIC;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_x)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_x)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Z;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_y)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_y)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Y;
    }
  }
  else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_z)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_z)) {
      process_model = true;
      scale = SCALE_ISOTROPIC_Z;
    }
  }
  if (m_config.findItem(SECTION_model, KEY_scale_anisotropic)) {
    if ((bool)m_config.getItem(SECTION_model, KEY_scale_anisotropic)) {
      process_model = true;
      scale = SCALE_ANISOTROPIC;
    }
  }
  
  if (process_model == true) {
    scale_object(m_static_objects, scale, align, ignore_minus_z);
  }


  contextCreated();

  m_initialised = true;
  return 0;
}