コード例 #1
0
ファイル: TrackballUI.c プロジェクト: thongle91/rubik-s-cube
void
ComputeQuat(vec4 RetQ, int SX, int SY, int EX, int EY)
{ vec3 p1, p2, d, rotAxis;
  float t, rotAngle;
  float p1x, p1y, p2x, p2y;
  
  if (SX == EX && SY == EY) {
    v4Set(RetQ,0,0,0,1);
    return;
  }
  
  p1x = 2 * ((SX / (float) WinWidth) - 0.5);
  p1y = -2 * ((SY / (float) WinHeight) - 0.5);
  p2x = 2 * ((EX / (float) WinWidth) - 0.5);
  p2y = -2 * ((EY / (float) WinHeight) - 0.5);
  
  v3Set(p1,p1x,p1y,ProjToSphere(TRACKBALL_SIZE,p1x,p1y));
  v3Set(p2,p2x,p2y,ProjToSphere(TRACKBALL_SIZE,p2x,p2y));
  v3Cross(p2,p1,rotAxis);
  
  v3Sub(p1,p2,d);
  t = CLAMP(v3Length(d) / (2.0 * TRACKBALL_SIZE),-1,1);
  rotAngle = 2.0 * asin(t);
  
  AxisToQuat(rotAxis,rotAngle,RetQ);
}
コード例 #2
0
ファイル: TrackballUI.c プロジェクト: thongle91/rubik-s-cube
void
CombineQuats(vec4 Q1, vec4 Q2, vec4 Dest)
{ vec3 t1, t2, t3;
  
  v3Copy(Q1,t1); v3Scale(t1,Q2[3]);
  v3Copy(Q2,t2); v3Scale(t2,Q1[3]);
  v3Cross(Q2,Q1,t3);
  v3Add(t1,t2,Dest);
  v3Add(t3,Dest,Dest);
  Dest[3] = Q1[3] * Q2[3] - v3Dot(Q1,Q2);
  v4Normalize(Dest);
}
コード例 #3
0
static bool decompose(const TransformationMatrix::Matrix4& mat, TransformationMatrix::DecomposedType& result)
{
    TransformationMatrix::Matrix4 localMatrix;
    memcpy(localMatrix, mat, sizeof(TransformationMatrix::Matrix4));

    // Normalize the matrix.
    if (localMatrix[3][3] == 0)
        return false;

    int i, j;
    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++)
            localMatrix[i][j] /= localMatrix[3][3];

    // perspectiveMatrix is used to solve for perspective, but it also provides
    // an easy way to test for singularity of the upper 3x3 component.
    TransformationMatrix::Matrix4 perspectiveMatrix;
    memcpy(perspectiveMatrix, localMatrix, sizeof(TransformationMatrix::Matrix4));
    for (i = 0; i < 3; i++)
        perspectiveMatrix[i][3] = 0;
    perspectiveMatrix[3][3] = 1;

    if (determinant4x4(perspectiveMatrix) == 0)
        return false;

    // First, isolate perspective.  This is the messiest.
    if (localMatrix[0][3] != 0 || localMatrix[1][3] != 0 || localMatrix[2][3] != 0) {
        // rightHandSide is the right hand side of the equation.
        Vector4 rightHandSide;
        rightHandSide[0] = localMatrix[0][3];
        rightHandSide[1] = localMatrix[1][3];
        rightHandSide[2] = localMatrix[2][3];
        rightHandSide[3] = localMatrix[3][3];

        // Solve the equation by inverting perspectiveMatrix and multiplying
        // rightHandSide by the inverse.  (This is the easiest way, not
        // necessarily the best.)
        TransformationMatrix::Matrix4 inversePerspectiveMatrix, transposedInversePerspectiveMatrix;
        inverse(perspectiveMatrix, inversePerspectiveMatrix);
        transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);

        Vector4 perspectivePoint;
        v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint);
 
        result.perspectiveX = perspectivePoint[0];
        result.perspectiveY = perspectivePoint[1];
        result.perspectiveZ = perspectivePoint[2];
        result.perspectiveW = perspectivePoint[3];
        
        // Clear the perspective partition
        localMatrix[0][3] = localMatrix[1][3] = localMatrix[2][3] = 0;
        localMatrix[3][3] = 1;
    } else {
        // No perspective.
        result.perspectiveX = result.perspectiveY = result.perspectiveZ = 0;
        result.perspectiveW = 1;
    }
    
    // Next take care of translation (easy).
    result.translateX = localMatrix[3][0];
    localMatrix[3][0] = 0;
    result.translateY = localMatrix[3][1];
    localMatrix[3][1] = 0;
    result.translateZ = localMatrix[3][2];
    localMatrix[3][2] = 0;

    // Vector4 type and functions need to be added to the common set.
    Vector3 row[3], pdum3;

    // Now get scale and shear.
    for (i = 0; i < 3; i++) {
        row[i][0] = localMatrix[i][0];
        row[i][1] = localMatrix[i][1];
        row[i][2] = localMatrix[i][2];
    }

    // Compute X scale factor and normalize first row.
    result.scaleX = v3Length(row[0]);
    v3Scale(row[0], 1.0);

    // Compute XY shear factor and make 2nd row orthogonal to 1st.
    result.skewXY = v3Dot(row[0], row[1]);
    v3Combine(row[1], row[0], row[1], 1.0, -result.skewXY);

    // Now, compute Y scale and normalize 2nd row.
    result.scaleY = v3Length(row[1]);
    v3Scale(row[1], 1.0);
    result.skewXY /= result.scaleY;

    // Compute XZ and YZ shears, orthogonalize 3rd row.
    result.skewXZ = v3Dot(row[0], row[2]);
    v3Combine(row[2], row[0], row[2], 1.0, -result.skewXZ);
    result.skewYZ = v3Dot(row[1], row[2]);
    v3Combine(row[2], row[1], row[2], 1.0, -result.skewYZ);

    // Next, get Z scale and normalize 3rd row.
    result.scaleZ = v3Length(row[2]);
    v3Scale(row[2], 1.0);
    result.skewXZ /= result.scaleZ;
    result.skewYZ /= result.scaleZ;
 
    // At this point, the matrix (in rows[]) is orthonormal.
    // Check for a coordinate system flip.  If the determinant
    // is -1, then negate the matrix and the scaling factors.
    v3Cross(row[1], row[2], pdum3);
    if (v3Dot(row[0], pdum3) < 0) {
        for (i = 0; i < 3; i++) {
            result.scaleX *= -1;
            row[i][0] *= -1;
            row[i][1] *= -1;
            row[i][2] *= -1;
        }
    }
 
    // Now, get the rotations out, as described in the gem.
    
    // FIXME - Add the ability to return either quaternions (which are
    // easier to recompose with) or Euler angles (rx, ry, rz), which
    // are easier for authors to deal with. The latter will only be useful
    // when we fix https://bugs.webkit.org/show_bug.cgi?id=23799, so I
    // will leave the Euler angle code here for now.

    // ret.rotateY = asin(-row[0][2]);
    // if (cos(ret.rotateY) != 0) {
    //     ret.rotateX = atan2(row[1][2], row[2][2]);
    //     ret.rotateZ = atan2(row[0][1], row[0][0]);
    // } else {
    //     ret.rotateX = atan2(-row[2][0], row[1][1]);
    //     ret.rotateZ = 0;
    // }
    
    double s, t, x, y, z, w;

    t = row[0][0] + row[1][1] + row[2][2] + 1.0;

    if (t > 1e-4) {
        s = 0.5 / sqrt(t);
        w = 0.25 / s;
        x = (row[2][1] - row[1][2]) * s;
        y = (row[0][2] - row[2][0]) * s;
        z = (row[1][0] - row[0][1]) * s;
    } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { 
        s = sqrt (1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx 
        x = 0.25 * s;
        y = (row[0][1] + row[1][0]) / s; 
        z = (row[0][2] + row[2][0]) / s; 
        w = (row[2][1] - row[1][2]) / s;
    } else if (row[1][1] > row[2][2]) { 
        s = sqrt (1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy
        x = (row[0][1] + row[1][0]) / s; 
        y = 0.25 * s;
        z = (row[1][2] + row[2][1]) / s; 
        w = (row[0][2] - row[2][0]) / s;
    } else { 
        s = sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz
        x = (row[0][2] + row[2][0]) / s;
        y = (row[1][2] + row[2][1]) / s; 
        z = 0.25 * s;
        w = (row[1][0] - row[0][1]) / s;
    }

    result.quaternionX = x;
    result.quaternionY = y;
    result.quaternionZ = z;
    result.quaternionW = w;
    
    return true;
}
コード例 #4
0
void SbPaint::Update()
{
    if( ShTouch::IsShaken() )
    {
        m_isClear = BtTrue;
    }
    if( UiKeyboard::pInstance()->IsPressed( UiKeyCode_R ) )
    {
        Reset();
    }
	if (UiKeyboard::pInstance()->IsPressed(UiKeyCode_S))
	{
		m_hardness = 0.25f;
	}

    // Get the rotational angle
    MtMatrix4 m4Transform = ExWAX9::GetTransform();
    MtVector3 v3XAxis = m4Transform.XAxis();
  
    m_roll = v3XAxis.y;  
    m_isRender = BtFalse;
	m_isBlob = BtFalse;

	// Calculate the thickness
	BtFloat edge = MtAbs(m_roll);
	BtFloat minWidth = RsUtil::GetHeight() * 0.001f;
	BtFloat maxWidth = RsUtil::GetHeight() * 0.010f;
	BtFloat width = MtLerp(edge, minWidth, maxWidth);
	m_thickness = width * MaxThickness * m_hardness;

	BtU32 colour = RsColour::BlueColour().asWord();

    for(BtU32 i=0; i<MaxTouches; i++ )
    {
        MtVector2 v2Position = ShTouch::GetPosition(i);

        if( ShTouch::IsPressed(i) )
        {
            m_v2Last = v2Position;
			m_isFirst = BtTrue;
        }
           
        if( ShTouch::IsHeld(i) )
        {
            m_isPainting = BtTrue;
            
            MtVector2 v2Delta = v2Position - m_v2Last;

//			m_hardness += BtTime::GetTick();

            if (v2Delta.GetLength() > 0.01f) // 1% = 11 pixels of 1080p
            {
				// Increase the thickness
				m_hardness += 0.1f;
				if (m_hardness > 1.0f)
				{
					m_hardness = 1.0f;
				}
				m_thickness = width * MaxThickness * m_hardness;
                
				MtVector2 v2ScreenPosition = GetScreenPositionFromMouse( v2Position );

                MtVector3 v3Delta( v2Delta.x, v2Delta.y, 0 );
				v3Delta.Normalise();
				
				MtVector3 v3Cross(v3Delta.y, v3Delta.x, 0);
                v3Cross *= m_thickness;
                
                if( m_isFirst == BtTrue )
                {
					MtVector2 v2LastScreenPosition = GetScreenPositionFromMouse( m_v2Last );
                    m_v2LastL = v2LastScreenPosition + MtVector2(-v3Cross.x, -v3Cross.y);
					m_v2LastR = v2LastScreenPosition + MtVector2( v3Cross.x,  v3Cross.y);
					m_isFirst = BtFalse;
                }
                else
                {
                    m_strokeVertex[0].m_v2Position = m_v2LastR;
					m_strokeVertex[0].m_colour = colour;
					m_strokeVertex[0].m_v2UV = MtVector2(0.5, 0.5);
                    
                    m_strokeVertex[1].m_v2Position = m_v2LastL;
					m_strokeVertex[1].m_colour = colour;
					m_strokeVertex[1].m_v2UV = MtVector2(0.5, 0.5);
                    
                    m_strokeVertex[2].m_v2Position = v2ScreenPosition + MtVector2(v3Cross.x, v3Cross.y);
					m_strokeVertex[2].m_colour = colour;
					m_strokeVertex[2].m_v2UV = MtVector2(0.5, 0.5);
                    
                    m_strokeVertex[3].m_v2Position = v2ScreenPosition + MtVector2(-v3Cross.x, -v3Cross.y);
					m_strokeVertex[3].m_colour = colour;
					m_strokeVertex[3].m_v2UV = MtVector2(0.5, 0.5);

					m_v2LastR = m_strokeVertex[2].m_v2Position;
					m_v2LastL = m_strokeVertex[3].m_v2Position;
                    
                    m_isRender = BtTrue;
                }

				m_v2Last = v2Position;
            }

			if (1)
			{
				m_isBlob = BtTrue;

				MtVector2 v2ScreenPosition = GetScreenPositionFromMouse(v2Position);

				MtVector3 v3Cross(m_thickness, m_thickness, 0);

				m_blobVertex[0].m_v2Position = v2ScreenPosition + MtVector2(-v3Cross.x, -v3Cross.y);
				m_blobVertex[0].m_colour = colour;
				m_blobVertex[0].m_v2UV = MtVector2(0, 0);

				m_blobVertex[1].m_v2Position = v2ScreenPosition + MtVector2(-v3Cross.x,  v3Cross.y);
				m_blobVertex[1].m_colour = colour;
				m_blobVertex[1].m_v2UV = MtVector2(0, 1);

				m_blobVertex[2].m_v2Position = v2ScreenPosition + MtVector2( v3Cross.x, -v3Cross.y);
				m_blobVertex[2].m_colour = colour;
				m_blobVertex[2].m_v2UV = MtVector2(1, 0);

				m_blobVertex[3].m_v2Position = v2ScreenPosition + MtVector2( v3Cross.x,  v3Cross.y);
				m_blobVertex[3].m_colour = colour;
				m_blobVertex[3].m_v2UV = MtVector2(1, 1);
			}
		}
        else if(ShTouch::IsReleased(i))
        {
            m_isFirst = BtTrue;
            m_v2Last  = v2Position;
        }
    }
}