void glm_transform(Transform M, GLMmodel *model) { Vect V, V_prime; // directly iterate over vertices -- indices seems to start at 1 for (int i = 1; i <= model->numvertices; i++) { V[X] = model->vertices[3 * i]; V[Y] = model->vertices[3 * i + 1]; V[Z] = model->vertices[3 * i + 2]; V[W] = 1.0; TransformVect(M, V, V_prime); model->vertices[3 * i] = V_prime[X]; model->vertices[3 * i + 1] = V_prime[Y]; model->vertices[3 * i + 2] = V_prime[Z]; } }
void parse_scene_file(char *filename, Camera *cam) { char c, obj_filename[64]; int w, h; FILE *fp; float sx, sy, sz, rx, ry, rz, dx, dy, dz; // scale factors, rotation angles (degrees), translation factors Transform Tmat, Rmat, Smat, scratchmat, Mmat; Vect P; Light *L; Surface *S; Sphere *Sph; // read file fp = fopen(filename, "r"); // camera position fscanf(fp, "camera %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", &cam->eye[X], &cam->eye[Y], &cam->eye[Z], &cam->center[X], &cam->center[Y], &cam->center[Z], &cam->up[X], &cam->up[Y], &cam->up[Z]); setup_lookat_transform(cam->W2C, cam->eye, cam->center, cam->up); // clip planes fscanf(fp, "clip %lf %lf %lf %lf %lf %lf\n", &cam->clip[LEFT], &cam->clip[RIGHT], &cam->clip[BOTTOM], &cam->clip[TOP], &cam->clip[NEAR], &cam->clip[FAR]); // image dimensions fscanf(fp, "image %i %i\n", &w, &h); cam->im = make_image(w, h); // objects and lights model_list.clear(); model_surf_list.clear(); sphere_list.clear(); light_list.clear(); while (1) { c = fgetc(fp); // end of file if (c == EOF) return; // it's a comment if (c == '#') { do { c = fgetc(fp); printf("eating %c\n", c); } while (c != '\n' && c != EOF); if (c == EOF) return; printf("done\n"); } // it's an object else if (c == 'o') { S = (Surface *) malloc(sizeof(Surface)); fscanf(fp, "bj %s %f %f %f %f %f %f %f %f %f %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", obj_filename, &dx, &dy, &dz, &sx, &sy, &sz, &rx, &ry, &rz, &(S->amb[R]), &(S->amb[G]), &(S->amb[B]), &(S->diff[R]), &(S->diff[G]), &(S->diff[B]), &S->spec[R], &S->spec[G], &S->spec[B], &S->spec_exp, &S->ior, &S->reflectivity, &S->transparency); GLMmodel *model = glmReadOBJ(obj_filename); if (!model) { printf("no such glm model %s\n", obj_filename); exit(1); } // scale and center model on origin glmUnitize(model); // build model transformations (including lookat world -> camera transform) TransformIdentity(Tmat); MATRC(Tmat, 0, 3) = dx; MATRC(Tmat, 1, 3) = dy; MATRC(Tmat, 2, 3) = dz; TransformIdentity(Smat); MATRC(Smat, 0, 0) = sx; MATRC(Smat, 1, 1) = sy; MATRC(Smat, 2, 2) = sz; model->position[0] = dx; model->position[1] = dy; model->position[2] = dz; // ROTATION WOULD GO HERE TransformProd(Tmat, Smat, scratchmat); TransformProd(cam->W2C, scratchmat, Mmat); //TransformPrint(Mmat); // apply transform to model glm_transform(Mmat, model); // calculate normals glmFacetNormals(model); glmVertexNormals(model, 90.0); model->index = model_list.size(); model_list.push_back(model); model_surf_list.push_back(S); } // it's a sphere else if (c == 's') { S = (Surface *) malloc(sizeof(Surface)); Sph = (Sphere *) malloc(sizeof(Sphere)); fscanf(fp, "phere %f %f %f %f %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", &dx, &dy, &dz, // position &sx, // size &(S->amb[R]), &(S->amb[G]), &(S->amb[B]), &(S->diff[R]), &(S->diff[G]), &(S->diff[B]), &S->spec[R], &S->spec[G], &S->spec[B], &S->spec_exp, &S->ior, &S->reflectivity, &S->transparency); Sph->P[X] = dx; Sph->P[Y] = dy; Sph->P[Z] = dz; Sph->radius = sx; Sph->surf = S; sphere_list.push_back(Sph); } // it's a light else if (c == 'l') { L = (Light *) malloc(sizeof(Light)); fscanf(fp, "ight %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n", &P[X], &P[Y], &P[Z], &L->amb[R], &L->amb[G], &L->amb[B], &L->diff[R], &L->diff[G], &L->diff[B], &L->spec[R], &L->spec[G], &L->spec[B]); // move to camera coordinates P[W] = 0; TransformVect(cam->W2C, P, L->P); // add to list light_list.push_back(L); } // unknown else if (c == '\n' && c != ' ' && c != '\t') { printf("bad scene syntax %c\n", c); exit(1); } } }
// event handlers void EEViewPort::OnMouseMove(wxMouseEvent& event) { // Update the status bar char strPosition[128]; std::stringstream ss; ss << event.GetX() << ", " << event.GetY(); ss.get(strPosition, 128); static_cast<wxFrame*>(wxTheApp->GetTopWindow())->SetStatusText(strPosition, 1); Vector2 mousePos = Vector2::Create(event.GetX(), event.GetY()); Vector2 deltaPos = mousePos - m_LastMousePosition; Camera* pCamera = EntityRenderer::Instance()->Get3DCamera(); if(m_bZoomingStarted) { CameraManager::Instance()->ZoomCamera(pCamera, deltaPos.Y); } else if(m_bLookingStarted) { CameraManager::Instance()->RotateCamera(pCamera, deltaPos); } else if (m_bStrafingStarted) { CameraManager::Instance()->StrafeCamera(pCamera, deltaPos); } else { // determine the selected triangle m_SelectedTriangleIndex = -1; m_SelectedSubMeshIndex = -1; static_cast<wxFrame*>(wxTheApp->GetTopWindow())->SetStatusText("", 3); ExplosionEditor* pEditor = static_cast<ExplosionEditor*>(wxTheApp->GetTopWindow()); if(MeshEntity* pMesh = pEditor->GetCurrentMesh()) { Vector3 rayStart, rayDir; pCamera->Get3DRayFromScreenPos(rayStart, rayDir, mousePos); float fMinDist = Math::Maxf32; std::vector<SubMesh*> subMeshes = pMesh->GetSubMeshes(); for(uint i=0; i<subMeshes.size(); ++i) { VertexBuffer* pVertexBuffer = subMeshes[i]->GetComponent<GraphicComponent>()->GetVertexBuffer(); //ushort* pIndices = (ushort*)pVertexBuffer->GetIndices(); //uint numTriangles = pVertexBuffer->GetNumIndices() / 3; Vertex3D* pVertices = reinterpret_cast<Vertex3D*>(pVertexBuffer->GetVertices()); uint numTriangles = pVertexBuffer->GetNumVertices() / 3; auto transform = subMeshes[i]->GetWorldTransform(); for (uint j = 0; j<numTriangles; ++j) { uint index1 = j * 3 + 0; uint index2 = j * 3 + 1; uint index3 = j * 3 + 2; Vector3 v1 = transform.TransformVect(pVertices[index1].Pos); Vector3 v2 = transform.TransformVect(pVertices[index2].Pos); Vector3 v3 = transform.TransformVect(pVertices[index3].Pos); Plane plane(v1, v2, v3); Vector3 vIntersection; Plane::E_Classification eClass; if(plane.IntersectWithRay(rayStart, rayDir, &vIntersection, &eClass)) { if(eClass == Plane::C_Front) { Triangle triangle(v1, v2, v3); if(triangle.IsPointInside(vIntersection)) { float fDist = (vIntersection - rayStart).GetLengthSquared(); if(fDist < fMinDist) { m_SelectedTriangleIndex = j; m_SelectedSubMeshIndex = i; fMinDist = fDist; } } } } } } if(m_SelectedTriangleIndex >= 0) { char buf[128]; std::stringstream ss; ss << "SubMesh: " << m_SelectedSubMeshIndex; ss.get(buf, 128); static_cast<wxFrame*>(wxTheApp->GetTopWindow())->SetStatusText(buf, 3); } } } m_LastMousePosition = mousePos; }