#include #include #include "Application.hxx" Application *MyApp; extern "C" { #include } int callbackSelectStory(char * story); int main(int argc, char *argv[]) { MyApp = new Application(); MyApp->make_objects(); MyApp->Loop(); pfExit(); return 0; } Application::Application() { // Initialize Performer pfInit(); pfMultiprocess(PFMP_APPCULLDRAW); pfConfig(); pfuInitUtil(); pipe = new Pipe(1280, 1024); pipe->Setup(); pick = new Pick(pipe->GetChan()); element_list = new List(); } void Application::Loop() { while(process_event()) { pipe->UpdateCam(); pfFrame(); } } // configuration of the placement and look of things // blur and transparencies of stories in the back, front float backBlur = 0.85; float backTrans = 0.37; float frontBlur = 0; float frontTrans = 1.0; // table of where the 5 stories go // the 0th position is the front-and-center story. float xpos[5] = { -12, -44, -24, 2, 22}; float ypos[5] = { 88, 110, 110, 110, 110 }; float zpos[5] = { 42, -10, 67, 67, -10 }; int positionIndices[5] = { 0, 1, 2, 3, 4 }; // colours for the five stories float rcol[5] = { 1.0, 1.0, 0.5, 1.0, 0.7 }; float gcol[5] = { 1.0, 0.5, 1.0, 0.7, 0.7 }; float bcol[5] = { 0.5, 1.0, 1.0, 0.7, 1.0 }; // workhorse function - handle when a story is selected void Application::selectStory(int newStory) { float backx, backy, backz, frontx, fronty, frontz; int numFrames = 10; int i; if (newStory == selectedStory) // no change really return; // this doesn't work for some reason // stories[newStory]->GetPosition(&backx, &backy, &backz); // the new story is going to go to the front frontx = xpos[0]; fronty = ypos[0]; frontz = zpos[0]; // the old story is going where the new story was before backx = xpos[positionIndices[newStory]]; backy = ypos[positionIndices[newStory]]; backz = zpos[positionIndices[newStory]]; // the old selected story is now where the new one is now positionIndices[selectedStory] = positionIndices[newStory]; // printf("Swapping (%f,%f,%f) and (%f,%f,%f)\n", backx, backy, backz, frontx, fronty, frontz); // animate swapping the two stories for (i = 0; i <= numFrames; i++) { float k = (float)i / (float)numFrames; // how far along? // make the old story blurry and put it where the one we selected is stories[selectedStory]->SetTransparency(frontTrans*(1-k) + backTrans*k); stories[selectedStory]->SetBlur(frontBlur*(1-k) + backBlur*k); stories[selectedStory]->SetPosition(frontx * (1-k) + backx * k, fronty * (1-k) + backy * k, frontz * (1-k) + backz * k); // now bring the new story to the front and sharp stories[newStory]->SetTransparency(backTrans*(1-k) + frontTrans*k); stories[newStory]->SetBlur(backBlur*(1-k) + frontBlur*k); stories[newStory]->SetPosition(backx * (1-k) + frontx * k, backy * (1-k) + fronty * k, backz * (1-k) + frontz * k); pfFrame(); } selectedStory = newStory; } void Application::make_objects() { int i; char file[255]; // make 5 story objects and put them in the right places // also make them clickable for (i = 0; i < 5; i++) { sprintf(file, "text/story%d", i+1); stories[i] = new Story(file, "Futura_book", "Futura_bold"); stories[i]->SetColor(rcol[i], gcol[i], bcol[i]); stories[i]->SetPosition(xpos[i], ypos[i], zpos[i]); stories[i]->SetBlur(backBlur); stories[i]->SetTransparency(backTrans); stories[i]->AttachFunctionCall(JUSTDOWN, callbackSelectStory, (char *)i); AddPickable(stories[i]); AddChild(stories[i]); } selectedStory = 0; stories[0]->SetTransparency(frontTrans); stories[0]->SetBlur(frontBlur); // the position was set above } int Application::process_event () { if (getbutton (QKEY)) return 0; pick->UpdateMouse(); if (pick->ChanPick()) { SendMessage(pick->hit_geode, pick->mouse_state); } // number keys pick stories absolutely if (getbutton(ONEKEY)) { selectStory(0); } if (getbutton(TWOKEY)) { selectStory(1); } if (getbutton(THREEKEY)) { selectStory(2); } if (getbutton(FOURKEY)) { selectStory(3); } if (getbutton(FIVEKEY)) { selectStory(4); } if (getbutton (XKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->xyz[0] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->xyz[0] -= 1.0; } if (getbutton (YKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->xyz[1] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->xyz[1] -= 1.0; } if (getbutton (ZKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->xyz[2] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->xyz[2] -= 1.0; } if (getbutton (HKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->hpr[0] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->hpr[0] -= 1.0; } if (getbutton (PKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->hpr[1] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->hpr[1] -= 1.0; } if (getbutton (RKEY)) { if (getbutton (LEFTARROWKEY)) pipe->cam->hpr[2] += 1.0; if (getbutton (RIGHTARROWKEY)) pipe->cam->hpr[2] -= 1.0; } return 1; } int Application::AddPickable(Element *e) { element_list->AddToList((void *) e); return (1); } int Application::SendMessage(pfGeode *hit_geode, int id) { List *L; Element *element; for (L = element_list->GetFront(); L != element_list; L = L->GetFront()) { element = (Element *)L->GetItem(); if (element->MatchGeode(hit_geode)) { return (element->CallFunction(id)); } } return (0); } // C callback: when the mouse is clicked, it carries with it data // about which story was clicked int callbackSelectStory(char * story) { printf("Story %d selected\n", (int)story); MyApp->selectStory((int)story); return 1; }