Ejemplo n.º 1
0
void
Matrix4x4::RotateZ(double aTheta)
{
  // XXX Is double precision really necessary here
  double cosTheta = FlushToZero(cos(aTheta));
  double sinTheta = FlushToZero(sin(aTheta));

  float temp;

  temp = _11;
  _11 = cosTheta * _11 + sinTheta * _21;
  _21 = -sinTheta * temp + cosTheta * _21;

  temp = _12;
  _12 = cosTheta * _12 + sinTheta * _22;
  _22 = -sinTheta * temp + cosTheta * _22;

  temp = _13;
  _13 = cosTheta * _13 + sinTheta * _23;
  _23 = -sinTheta * temp + cosTheta * _23;

  temp = _14;
  _14 = cosTheta * _14 + sinTheta * _24;
  _24 = -sinTheta * temp + cosTheta * _24;
}
Ejemplo n.º 2
0
void
Matrix4x4::RotateY(double aTheta)
{
  // XXX Is double precision really necessary here
  double cosTheta = FlushToZero(cos(aTheta));
  double sinTheta = FlushToZero(sin(aTheta));

  float temp;

  temp = _11;
  _11 = cosTheta * _11 + -sinTheta * _31;
  _31 = sinTheta * temp + cosTheta * _31;

  temp = _12;
  _12 = cosTheta * _12 + -sinTheta * _32;
  _32 = sinTheta * temp + cosTheta * _32;

  temp = _13;
  _13 = cosTheta * _13 + -sinTheta * _33;
  _33 = sinTheta * temp + cosTheta * _33;

  temp = _14;
  _14 = cosTheta * _14 + -sinTheta * _34;
  _34 = sinTheta * temp + cosTheta * _34;
}
Ejemplo n.º 3
0
void
Matrix4x4::RotateX(double aTheta)
{
  // XXX Is double precision really necessary here
  double cosTheta = FlushToZero(cos(aTheta));
  double sinTheta = FlushToZero(sin(aTheta));

  float temp;

  temp = _21;
  _21 = cosTheta * _21 + sinTheta * _31;
  _31 = -sinTheta * temp + cosTheta * _31;

  temp = _22;
  _22 = cosTheta * _22 + sinTheta * _32;
  _32 = -sinTheta * temp + cosTheta * _32;

  temp = _23;
  _23 = cosTheta * _23 + sinTheta * _33;
  _33 = -sinTheta * temp + cosTheta * _33;

  temp = _24;
  _24 = cosTheta * _24 + sinTheta * _34;
  _34 = -sinTheta * temp + cosTheta * _34;
}
Ejemplo n.º 4
0
static void
ProcessRotate3D(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
{
  NS_PRECONDITION(aData->Count() == 5, "Invalid array!");

  /* We want our matrix to look like this:
   * |       1 + (1-cos(angle))*(x*x-1)   -z*sin(angle)+(1-cos(angle))*x*y   y*sin(angle)+(1-cos(angle))*x*z   0 |
   * |  z*sin(angle)+(1-cos(angle))*x*y         1 + (1-cos(angle))*(y*y-1)  -x*sin(angle)+(1-cos(angle))*y*z   0 |
   * | -y*sin(angle)+(1-cos(angle))*x*z    x*sin(angle)+(1-cos(angle))*y*z        1 + (1-cos(angle))*(z*z-1)   0 |
   * |                                0                                  0                                 0   1 |
   * (see http://www.w3.org/TR/css3-3d-transforms/#transform-functions)
   */

  /* The current spec specifies a matrix that rotates in the wrong direction. For now we just negate
   * the angle provided to get the correct rotation direction until the spec is updated.
   * See bug 704468.
   */
  double theta = -aData->Item(4).GetAngleValueInRadians();
  float cosTheta = FlushToZero(cos(theta));
  float sinTheta = FlushToZero(sin(theta));

  float x = aData->Item(1).GetFloatValue();
  float y = aData->Item(2).GetFloatValue();
  float z = aData->Item(3).GetFloatValue();

  /* Normalize [x,y,z] */
  float length = sqrt(x*x + y*y + z*z);
  if (length == 0.0) {
    return;
  }
  x /= length;
  y /= length;
  z /= length;

  gfx3DMatrix temp;

  /* Create our matrix */
  temp._11 = 1 + (1 - cosTheta) * (x * x - 1);
  temp._12 = -z * sinTheta + (1 - cosTheta) * x * y;
  temp._13 = y * sinTheta + (1 - cosTheta) * x * z;
  temp._14 = 0.0f;
  temp._21 = z * sinTheta + (1 - cosTheta) * x * y;
  temp._22 = 1 + (1 - cosTheta) * (y * y - 1);
  temp._23 = -x * sinTheta + (1 - cosTheta) * y * z;
  temp._24 = 0.0f;
  temp._31 = -y * sinTheta + (1 - cosTheta) * x * z;
  temp._32 = x * sinTheta + (1 - cosTheta) * y * z;
  temp._33 = 1 + (1 - cosTheta) * (z * z - 1);
  temp._34 = 0.0f;
  temp._41 = 0.0f;
  temp._42 = 0.0f;
  temp._43 = 0.0f;
  temp._44 = 1.0f;

  aMatrix = temp * aMatrix;
}
static void
ProcessRotate3D(Matrix4x4& aMatrix, const nsCSSValue::Array* aData)
{
  NS_PRECONDITION(aData->Count() == 5, "Invalid array!");

  /* We want our matrix to look like this:
   * |       1 + (1-cos(angle))*(x*x-1)   -z*sin(angle)+(1-cos(angle))*x*y   y*sin(angle)+(1-cos(angle))*x*z   0 |
   * |  z*sin(angle)+(1-cos(angle))*x*y         1 + (1-cos(angle))*(y*y-1)  -x*sin(angle)+(1-cos(angle))*y*z   0 |
   * | -y*sin(angle)+(1-cos(angle))*x*z    x*sin(angle)+(1-cos(angle))*y*z        1 + (1-cos(angle))*(z*z-1)   0 |
   * |                                0                                  0                                 0   1 |
   * (see http://www.w3.org/TR/css3-3d-transforms/#transform-functions)
   */

  /* The current spec specifies a matrix that rotates in the wrong direction. For now we just negate
   * the angle provided to get the correct rotation direction until the spec is updated.
   * See bug 704468.
   */
  double theta = -aData->Item(4).GetAngleValueInRadians();
  float cosTheta = FlushToZero(cos(theta));
  float sinTheta = FlushToZero(sin(theta));

  Point3D vector(aData->Item(1).GetFloatValue(),
                 aData->Item(2).GetFloatValue(),
                 aData->Item(3).GetFloatValue());

  if (!vector.Length()) {
    return;
  }
  vector.Normalize();

  Matrix4x4 temp;

  /* Create our matrix */
  temp._11 = 1 + (1 - cosTheta) * (vector.x * vector.x - 1);
  temp._12 = -vector.z * sinTheta + (1 - cosTheta) * vector.x * vector.y;
  temp._13 = vector.y * sinTheta + (1 - cosTheta) * vector.x * vector.z;
  temp._14 = 0.0f;
  temp._21 = vector.z * sinTheta + (1 - cosTheta) * vector.x * vector.y;
  temp._22 = 1 + (1 - cosTheta) * (vector.y * vector.y - 1);
  temp._23 = -vector.x * sinTheta + (1 - cosTheta) * vector.y * vector.z;
  temp._24 = 0.0f;
  temp._31 = -vector.y * sinTheta + (1 - cosTheta) * vector.x * vector.z;
  temp._32 = vector.x * sinTheta + (1 - cosTheta) * vector.y * vector.z;
  temp._33 = 1 + (1 - cosTheta) * (vector.z * vector.z - 1);
  temp._34 = 0.0f;
  temp._41 = 0.0f;
  temp._42 = 0.0f;
  temp._43 = 0.0f;
  temp._44 = 1.0f;

  aMatrix = temp * aMatrix;
}
/* static */ gfx3DMatrix
nsStyleTransformMatrix::ProcessRotate3D(const nsCSSValue::Array* aData)
{
  NS_PRECONDITION(aData->Count() == 5, "Invalid array!");

  /* We want our matrix to look like this:
   * |       1 + (1-cos(angle))*(x*x-1)   -z*sin(angle)+(1-cos(angle))*x*y   y*sin(angle)+(1-cos(angle))*x*z   0 |
   * |  z*sin(angle)+(1-cos(angle))*x*y         1 + (1-cos(angle))*(y*y-1)  -x*sin(angle)+(1-cos(angle))*y*z   0 |
   * | -y*sin(angle)+(1-cos(angle))*x*z    x*sin(angle)+(1-cos(angle))*y*z        1 + (1-cos(angle))*(z*z-1)   0 |
   * |                                0                                  0                                 0   1 |
   * (see http://www.w3.org/TR/css3-3d-transforms/#transform-functions)
   */
  double theta = aData->Item(4).GetAngleValueInRadians();
  float cosTheta = FlushToZero(cos(theta));
  float sinTheta = FlushToZero(sin(theta));

  float x = aData->Item(1).GetFloatValue();
  float y = aData->Item(2).GetFloatValue();
  float z = aData->Item(3).GetFloatValue();

  /* Normalize [x,y,z] */
  float length = sqrt(x*x + y*y + z*z);
  if (length == 0.0) {
    return gfx3DMatrix();
  }
  x /= length;
  y /= length;
  z /= length;

  gfx3DMatrix temp;

  /* Create our matrix */
  temp._11 = 1 + (1 - cosTheta) * (x * x - 1);
  temp._12 = -z * sinTheta + (1 - cosTheta) * x * y;
  temp._13 = y * sinTheta + (1 - cosTheta) * x * z;
  temp._14 = 0.0f;
  temp._21 = z * sinTheta + (1 - cosTheta) * x * y;
  temp._22 = 1 + (1 - cosTheta) * (y * y - 1);
  temp._23 = -x * sinTheta + (1 - cosTheta) * y * z;
  temp._24 = 0.0f;
  temp._31 = -y * sinTheta + (1 - cosTheta) * x * z;
  temp._32 = x * sinTheta + (1 - cosTheta) * y * z;
  temp._33 = 1 + (1 - cosTheta) * (z * z - 1);
  temp._34 = 0.0f;
  temp._41 = 0.0f;
  temp._42 = 0.0f;
  temp._43 = 0.0f;
  temp._44 = 1.0f;
  return temp;
}
/* Function that converts a rotate transform into a matrix. */
static void ProcessRotate(float aMain[4], const nsCSSValue::Array* aData)
{
  NS_PRECONDITION(aData->Count() == 2, "Invalid array!");

  /* We want our matrix to look like this:
   * |  cos(theta)  -sin(theta)  0|
   * |  sin(theta)   cos(theta)  0|
   * |           0            0  1|
   * (see http://www.w3.org/TR/SVG/coords.html#RotationDefined)
   */
  double theta = aData->Item(1).GetAngleValueInRadians();
  float cosTheta = FlushToZero(cos(theta));
  float sinTheta = FlushToZero(sin(theta));

  aMain[0] = cosTheta;
  aMain[1] = sinTheta;
  aMain[2] = -sinTheta;
  aMain[3] = cosTheta;
}
/* static */ gfx3DMatrix 
nsStyleTransformMatrix::ProcessRotateY(const nsCSSValue::Array* aData)
{
  NS_PRECONDITION(aData->Count() == 2, "Invalid array!");

  /* We want our matrix to look like this:
   * | cos(theta) 0 -sin(theta) 0 |
   * |          0 1           0 0 |
   * | sin(theta) 0  cos(theta) 0 |
   * | 0          0           0 1 |
   * (see http://www.w3.org/TR/SVG/coords.html#RotationDefined)
   */
  double theta = aData->Item(1).GetAngleValueInRadians();
  float cosTheta = FlushToZero(cos(theta));
  float sinTheta = FlushToZero(sin(theta));

  gfx3DMatrix temp;

  temp._11 = cosTheta;
  temp._13 = -sinTheta;
  temp._31 = sinTheta;
  temp._33 = cosTheta;
  return temp;
}
/* Computes tan(aTheta).  For values of aTheta such that tan(aTheta) is
 * undefined or very large, SafeTangent returns a manageably large value
 * of the correct sign.
 */
static double SafeTangent(double aTheta)
{
  const double kEpsilon = 0.0001;

  /* tan(theta) = sin(theta)/cos(theta); problems arise when
   * cos(theta) is too close to zero.  Limit cos(theta) to the
   * range [-1, -epsilon] U [epsilon, 1].
   */
  double sinTheta = sin(aTheta);
  double cosTheta = cos(aTheta);

  if (cosTheta >= 0 && cosTheta < kEpsilon)
    cosTheta = kEpsilon;
  else if (cosTheta < 0 && cosTheta >= -kEpsilon)
    cosTheta = -kEpsilon;

  return FlushToZero(sinTheta / cosTheta);
}