vec3_t *G2Exporter_Surface_GetVertNormal(int iSurfaceIndex, int iVertIndex, int iLODIndex) { static vec3_t v3={0}; memset(v3,0,sizeof(v3)); if (iLODIndex == giNumLODs-1) { // q3data surface... // if (iSurfaceIndex < giNumSurfaces) { // standard surface... // md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex); if (pSurfaceData) { // this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so... // float **ppVerts = pSurfaceData->verts; memcpy(v3,(vec3_t*) &ppVerts[0][iVertIndex*6+3], sizeof(v3)); { Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } } else { // tag surface... // // I don't think tag-surfaces normals have any meaning for ghoul2, so... // return &v3; } } else { // imported surface... // vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].normal; memcpy(v3,v3Src,sizeof(v3)); return &v3; } assert(0); return &v3; }
void TranslateMatrix4(const Vector3 &v, Matrix4 &result) { result.Identity(); result.wX = v.x; result.wY = v.y; result.wZ = v.z; }
MATHDLL_API Vector3 RotateAround(const Vector3 & axis, float amount, const Vector3 & vectorToRotate) { Matrix4 identity; identity.Identity(); Matrix4 first = identity * cos(amount); Matrix4 second = TensorProductMatrix(axis) * (1 - cos(amount)); Matrix4 third = CrossProductMatrix(axis) * sin(amount); Vector4 endVal = (first + second + third) * vectorToRotate; return Vector3(endVal.x, endVal.y, endVal.z); }
TEST(matrix4, identitymatrix) { Matrix4 m1(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); Matrix4 iD; iD.Identity(); EXPECT_TRUE(m1 == iD); }
void Matrix4::Rotate(Vector3 r) { Matrix4 m; float rx=DEGTORAD*r.x; float ry=DEGTORAD*r.y; float rz=DEGTORAD*r.z; m[1][1]=cos(rx); m[1][2]=sin(rx); m[2][1]=-sin(rx); m[2][2]=cos(rx); *this=(*this)*m; m.Identity(); m[0][0]=cos(ry); m[0][1]=sin(ry); m[2][1]=-sin(ry); m[2][2]=cos(ry); *this=(*this)*m; m.Identity(); m[0][0]=cos(rz); m[0][1]=sin(rz); m[1][0]=-sin(rz); m[1][1]=cos(rz); *this=(*this)*m; }
void CardinalOrthoProject(bool xAxis, bool yAxis, bool zAxis, Matrix4 &result) { result.Identity(); if (xAxis) result.xX = 0; if (yAxis) result.yY = 0; if (zAxis) result.zZ = 0; }
void EditorBodyControl::ApplyTransform(float32 x, float32 y, float32 z) { if (!InModificationMode()) return; Entity *selectedNode = scene->GetProxy(); if(selectedNode) { Matrix4 modification; modification.Identity(); Matrix4 t1, t2; t1.CreateTranslation(-selectedNode->GetWorldTransform().GetTranslationVector()); t2.CreateTranslation(selectedNode->GetWorldTransform().GetTranslationVector()); switch (GetModificationMode()) { case ResourceEditor::MODIFY_MOVE: modification.CreateTranslation(Vector3(x, y, z)); break; case ResourceEditor::MODIFY_ROTATE: modification.CreateRotation(Vector3(1, 0, 0), DegToRad(x)); modification *= Matrix4::MakeRotation(Vector3(0, 1, 0), DegToRad(y)); modification *= Matrix4::MakeRotation(Vector3(0, 0, 1), DegToRad(z)); modification = (t1 * modification) * t2; break; case ResourceEditor::MODIFY_SCALE: modification.CreateScale(Vector3(1, 1, 1) + Vector3(x + y + z, x + y + z, x + y + z) / 100.f); modification = (t1 * modification) * t2; break; default: break; } Matrix4 originalTransform = selectedNode->GetLocalTransform(); modification = originalTransform * modification; if (IsLandscapeRelative()) { modification = modification * GetLandscapeOffset(modification); } CommandsManager::Instance()->ExecuteAndRelease(new CommandTransformObject(selectedNode, originalTransform, modification), scene); } }
void NonUniformScaleMatrix4(float xAmount, float yAmount, float zAmount, Matrix4 &result) { result.Identity(); // Scale all dimensions by the ENGINEsponding amount. // As the result is identity, we remove unnecassary multiplications that will result in 0. // X axis vector * xAmount result.xX *= xAmount; // Y axis vector * yAmount result.yY *= yAmount; // Z axis vector * zAmount result.zZ *= zAmount; }
void UniformScaleMatrix4(float amount, Matrix4 &result) { result.Identity(); // Scale all dimensions by the amount. // As the result is identity, we remove unnecassary multiplications that will result in 0. // X axis vector result.xX *= amount; // Y axis vector result.yY *= amount; // Z axis vector result.zZ *= amount; }
void ModificationPopUp::OnFloatPropertyChanged(PropertyList *forList, const String &forKey, float newValue) { if (selection) { Matrix4 modification; modification.Identity(); modification.CreateTranslation(Vector3(forList->GetFloatPropertyValue("x"), forList->GetFloatPropertyValue("y"), forList->GetFloatPropertyValue("z"))); selection->SetLocalTransform(selection->GetLocalTransform() * modification); forList->SetFloatPropertyValue("x", 0.0f); forList->SetFloatPropertyValue("y", 0.0f); forList->SetFloatPropertyValue("z", 0.0f); } }
Matrix4 RPhysics::GetOrientTransform(Vector4 dirStart, Vector4 upStart1, Vector4 dirEnd, Vector4 upEnd1) { Vector4 temp = CrossProduct(dirStart,upStart1); Vector4 upStart = CrossProduct(temp,dirStart); temp = CrossProduct(dirEnd,upEnd1); Vector4 upEnd = CrossProduct(temp,dirEnd); dirStart = Normalize3(dirStart); dirEnd = Normalize3(dirEnd); upStart = Normalize3(upStart); upEnd = Normalize3(upEnd); Matrix4 transform; transform.Identity(); Vector4 axis1 = CrossProduct(dirStart,dirEnd); if(Length3(axis1)==0) axis1 = upEnd; float angle1 = Angle3(dirStart,dirEnd); Matrix4 rotMat; rotMat.Rotation(angle1,axis1); Vector4 newUp = rotMat*upStart; Vector4 axis2 = CrossProduct(newUp,upEnd); if(Length3(axis2)==0) axis2 = dirEnd; float angle2 = Angle3(upEnd,newUp); if(angle1*angle2*0!=0) return transform; Matrix4 toRot; toRot.Rotation(angle2,axis2); transform= transform*toRot; toRot.Rotation(angle1,axis1); transform = transform*toRot; if(!(transform[0][0]<=3||transform[0][0]>=3)) { cerr<<endl; cerr<<angle1<<endl; cerr<<angle2<<endl; PrintVector(dirStart); PrintVector(upStart); PrintVector(dirEnd); PrintVector(upEnd); cout<<flush; exit(1); } return transform; }
void ColladaScene::Render() { SetupDefaultLights(); ColladaLightState state; rootNode->PreProcessLights(state); if ((state.globalAmbientalLight[0] > 0.0f) || (state.globalAmbientalLight[1] > 0.0f) || (state.globalAmbientalLight[2] > 0.0f)) { glLightModelfv(GL_LIGHT_MODEL_AMBIENT, state.globalAmbientalLight); // draw a square at the center that represents the ambient light //if (show_lights) { glDisable(GL_LIGHTING); glColor3f(0.984375, 0.078125, 0.64453125); //glutWireCube(1.0f); glEnable(GL_LIGHTING); glColor3f(1.0f, 1.0f, 1.0f); } } // printf("Light Count: %d\n", state.lightIndex); currentTime += SystemTimer::FrameDelta(); if (currentTime >= animationEndTime) currentTime = 0; rootNode->UpdateTransforms(currentTime); for (int ameshIndex = 0; ameshIndex < (int) colladaAnimatedMeshes.size(); ++ameshIndex) { ColladaAnimatedMesh * animMesh = colladaAnimatedMeshes[ameshIndex]; animMesh->UpdateSkinnedMesh(currentTime); } Matrix4 base; base.Identity(); rootNode->Render(base); RenderAxes(); }
Matrix4 EditorBodyControl::GetLandscapeOffset(const Matrix4& transform) { Matrix4 resTransform; resTransform.Identity(); Landscape* landscape = FindLandscape(scene); if(!landscape) return resTransform; Vector3 p = Vector3(0, 0, 0) * transform; Vector3 result; bool res = landscape->PlacePoint(p, result); if (res) { Vector3 offset = result - p; resTransform.CreateTranslation(offset); } return resTransform; }
void RotateMatrix4Y(float angle, Matrix4 &result) { // Y axis rotation // /-- --\ // | cosT 0 -sinT | // | 0 1 0 | // | sinT 0 cosT | // \-- --/ result.Identity(); // Convert angle to radian float theta = ToRadian(angle); float sine, cosine; SinCos(cosine, sine, theta); // X axis rotation result.xX = cosine; result.xZ = -sine; // Z axis rotation result.zX = sine; result.zZ = cosine; }
void Matrix4::Uviewpoint(const Coord3D& v1, const Coord3D& v2, const Coord3D& up) { // find the vector that points in the v21 direction Coord3D v_hat_21 = v2 - v1; // compute rotation matrix that takes -z axis to the v21 axis, // and y to the up direction Matrix4 rotMat; rotMat.UviewDirection(v_hat_21, up); // build matrix that translates the origin to v1 Matrix4 transMat; transMat.Identity(); transMat.m[3][0] = v1.cX; transMat.m[3][1] = v1.cY; transMat.m[3][2] = v1.cZ; // concatenate the matrices together MatrixProduct(rotMat, transMat); }
void RotateMatrix4Z(float angle, Matrix4 &result) { // Z axis rotation // /-- --\ // | cosT sinT 0 | // |-sinT cosT 0 | // | 0 0 1 | // \-- --/ result.Identity(); // Convert angle to radian float theta = ToRadian(angle); float sine, cosine; SinCos(cosine, sine, theta); // X axis rotation result.xX = cosine; result.xY = sine; // Y axis rotation; result.yX = -sine; result.yY = cosine; }
void RotateMatrix4X(float angle, Matrix4 &result) { // X axis rotation // /-- --\ // | 1 0 0 | // | 0 cosT -sinT | // | 0 sinT cosT | // \-- --/ result.Identity(); // Convert angle to radian float theta = ToRadian(angle); float sine, cosine; SinCos(cosine, sine, theta); // Y axis rotation result.yY = cosine; result.yZ = -sine; // Z axis rotation result.zY = sine; result.zZ = cosine; }
void Matrix4::UviewDirection(const Coord3D& v21, const Coord3D& up) { double sine, cosine; // find the unit vector that points in the v21 direction Coord3D v_hat_21(v21); double len = v_hat_21.Magnitude(); Matrix4 amat; if (fabs(len) > stdEps) { len = 1.0 / len; v_hat_21 *= len; // rotate z in the xz-plane until same latitude sine = sqrt (1.0 - v_hat_21.cZ * v_hat_21.cZ); amat.RotateY(-v_hat_21.cZ, -sine); } else // error condition: zero length vecotr passed in -- do nothing */ amat.Identity(); // project v21 onto the xy plane Coord3D v_xy(v21); v_xy.cZ = 0.0; len = v_xy.Magnitude(); // rotate in the x-y plane until v21 lies on z axis --- // but of course, if its already there, do nothing Matrix4 bmat, cmat; if (fabs(len) > stdEps) { // want xy projection to be unit vector, so that sines/cosines pop out len = 1.0 / len; v_xy *= len; // rotate the projection of v21 in the xy-plane over to the x axis bmat.RotateZ(v_xy.cX, v_xy.cY); // concatenate these together cmat.MatrixProduct(amat, bmat); } else cmat = amat; /* up vector really should be perpendicular to the x-form direction -- * Use up a couple of cycles, and make sure it is, * just in case the user blew it. */ Coord3D up_proj; up_proj.Perpendicular(up, v_hat_21); len = up_proj.Magnitude(); if (fabs(len) > stdEps) { // normalize the vector len = 1.0/len; up_proj *= len; // compare the up-vector to the y-axis to get the cosine of the angle Coord3D tmp; tmp.cX = cmat.m[1][0]; tmp.cY = cmat.m[1][1]; tmp.cZ = cmat.m[1][2]; cosine = tmp.Dot(up_proj); // compare the up-vector to the x-axis to get the sine of the angle tmp.cX = cmat.m[0][0]; tmp.cY = cmat.m[0][1]; tmp.cZ = cmat.m[0][2]; sine = tmp.Dot(up_proj); // rotate to align the up vector with the y-axis amat.RotateZ(cosine, -sine); // This xform, although computed last, acts first MatrixProduct(amat, cmat); } else { // error condition: up vector is indeterminate (zero length) // -- do nothing *this = cmat; } }
vec3_t *G2Exporter_Surface_GetVertCoords(int iSurfaceIndex, int iVertIndex, int iLODIndex) { static vec3_t v3={0}; memset(&v3,0,sizeof(v3)); if (iLODIndex == giNumLODs-1) { // q3data surface... // if (iSurfaceIndex < giNumSurfaces) { // standard surface... // md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex); if (pSurfaceData) { // this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so... // float **ppVerts = pSurfaceData->verts; static vec3_t v3; for (int i=0; i<3; i++) { v3[i] = ppVerts[0][iVertIndex*6+i];// /MD3_XYZ_SCALE; } // return &v3; Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } else { // tag surface... // assert(iVertIndex<3); md3Tag_t *pTag = &g_data.tags[0][iSurfaceIndex - giNumSurfaces]; vec3_t v3New; //#ifdef PERFECT_CONVERSION v3New[0] = pTag->axis[0][iVertIndex] ; v3New[1] = pTag->axis[1][iVertIndex] ; v3New[2] = pTag->axis[2][iVertIndex] ; // don't worry about how this crap works, it just does (arrived at by empirical methods... :-) // // (mega-thanks to Gil as usual) // if (iVertIndex==2) { VectorCopy(pTag->origin,v3); } else if (iVertIndex==1) { v3New[0] = 2.0f * pTag->axis[1][iG2_TRISIDE_MIDDLE]; v3New[1] = -(2.0f * pTag->axis[0][iG2_TRISIDE_MIDDLE]); v3New[2] = 2.0f * pTag->axis[2][iG2_TRISIDE_MIDDLE]; VectorSubtract(pTag->origin,v3New,v3); } else { v3New[0] = pTag->axis[1][iG2_TRISIDE_LONGEST]; v3New[1] = -pTag->axis[0][iG2_TRISIDE_LONGEST]; v3New[2] = pTag->axis[2][iG2_TRISIDE_LONGEST]; VectorSubtract(pTag->origin,v3New,v3); } // return (vec3_t*) &v3; Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } else { // imported surface... // vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].vertCoords; memcpy(v3,v3Src,sizeof(v3)); return &v3; } assert(0); return &v3; }
void EditorBodyControl::PrepareModMatrix(const Vector2 & point) { float32 winx = point.x - touchStart.x; float32 winy = point.y - touchStart.y; Matrix4 modification; modification.Identity(); ArrowsNode* arrowsNode = GetArrowsNode(false); if (!arrowsNode) return; if (GetModificationMode() == ResourceEditor::MODIFY_MOVE) { Vector3 from, dir; GetCursorVectors(&from, &dir, point); Vector3 currPoint; bool result = GetIntersectionVectorWithPlane(from, dir, planeNormal, rotationCenter, currPoint); if (result) { if (arrowsNode) { switch (arrowsNode->GetModAxis()) { case ArrowsNode::AXIS_X: currPoint.y = startDragPoint.y; currPoint.z = startDragPoint.z; break; case ArrowsNode::AXIS_Y: currPoint.x = startDragPoint.x; currPoint.z = startDragPoint.z; break; case ArrowsNode::AXIS_Z: currPoint.x = startDragPoint.x; currPoint.y = startDragPoint.y; break; default: break; } modification.CreateTranslation(currPoint - startDragPoint); } } } else if (GetModificationMode() == ResourceEditor::MODIFY_ROTATE) { Matrix4 d; switch (arrowsNode->GetModAxis()) { case ArrowsNode::AXIS_X: case ArrowsNode::AXIS_Y: modification.CreateRotation(vect[arrowsNode->GetModAxis()], winy / 100.0f); break; case ArrowsNode::AXIS_Z: modification.CreateRotation(vect[arrowsNode->GetModAxis()], winx / 100.0f); break; case ArrowsNode::AXIS_XY: modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f); d.CreateRotation(vect[ArrowsNode::AXIS_Y], winy / 100.0f); modification *= d; break; case ArrowsNode::AXIS_YZ: modification.CreateRotation(vect[ArrowsNode::AXIS_Y], winx / 100.0f); d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f); modification *= d; break; case ArrowsNode::AXIS_XZ: modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f); d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f); modification *= d; break; default: break; } modification = (translate1 * modification) * translate2; } else if (GetModificationMode() == ResourceEditor::MODIFY_SCALE) { float kf = winx / 100.0f; if (kf < -1.0) kf = - kf - 2.0; modification.CreateScale(Vector3(1,1,1) + Vector3(1,1,1) * kf); modification = (translate1 * modification) * translate2; } currTransform = startTransform * modification; }