// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // ViewerHOOPS.cpp // Display of VRML models using HOOPS (www.hoops3d.com). // #include "config.h" #if HAVE_HOOPS #include "ViewerHOOPS.h" #include #include #include #include #include "HOOPSEvent.h" #include "VrmlScene.h" ViewerHOOPS::ViewerHOOPS(VrmlScene *scene) : Viewer(scene) { char window[100]; int nWindows = 0; // Avoid immediate exits, gratuitous call to ps HC_Define_System_Options("no message limit,application=VRML"); // Generate a unique top level segment name by counting top level segments HC_Show_Alias("?Picture", window); HC_Begin_Segment_Search(window); HC_Show_Segment_Count(&nWindows); HC_End_Segment_Search(); // Get rid of the nominal Picture if (nWindows != 0) // if it still exists, as we will HC_Delete_Segment(window); // create our own. strcat(window,"*"); HC_Begin_Segment_Search(window); HC_Show_Segment_Count(&nWindows); HC_End_Segment_Search(); sprintf(&window[strlen(window)-1], "+%d", nWindows); // One-time initializations and top level settings if (nWindows == 0) { HC_Open_Segment("/driver"); { HC_Set_Handedness("right"); HC_Set_Color("geometry=white,windows=black,light=gray"); // Enable back plane culling of shells HC_Set_Heuristics("polygon handedness=left"); // Lighting of faces only. HC_Set_Rendering_Options("color index interpolation=off," "color interpolation=(edges=off,faces=on)"); HC_Set_Selectability("windows=v*^"); HC_Set_Visibility("markers=off,faces=on,edges=off"); HC_Set_Visibility("lighting=(edges=off,markers=off)"); } HC_Close_Segment(); } // Open and initialize the window d_windowKey = HC_KOpen_Segment(window); { // Window size (left,right,bottom,top) from -1 to 1 in each direction HC_Set_Driver_Options("subscreen=(-.5,.5,-.5,.5)"); char title[40], driver[20]; HC_Show_Device_Info(".", "driver type", driver); sprintf(title,"title='VRML HOOPS/%s Viewer [%d]'", driver, nWindows); HC_Set_Driver_Options(title); HC_Set_Window(-1.0,1.0,-1.0,1.0); HC_Enable_Selection_Events(".", "."); HC_Enable_Button_Events(".", "everything"); } HC_Close_Segment(); d_nTextures = 0; } ViewerHOOPS::~ViewerHOOPS() { HC_Delete_By_Key(d_windowKey); } void ViewerHOOPS::beginUpdate() { d_nTextures = 0; HC_Open_Segment_By_Key(d_windowKey); } void ViewerHOOPS::endUpdate() { HC_Close_Segment(); } // // Object creation. // Objects can be referred to later to avoid duplicating geometry // Viewer::Object ViewerHOOPS::beginObject(const char *name, bool) { return HC_KOpen_Segment(name); } void ViewerHOOPS::endObject() { HC_Close_Segment(); } // Queries void ViewerHOOPS::getPosition( float *x, float *y, float *z ) // ... { *x = 0.0; *y = 0.0; *z = 0.0; } void ViewerHOOPS::getOrientation( float *orientation ) // ... { orientation[0] = 0.0; orientation[1] = 1.0; orientation[2] = 0.0; orientation[3] = 0.0; } int ViewerHOOPS::getRenderMode() { return RENDER_MODE_DRAW; } double ViewerHOOPS::getRenderMode() { return 0.0; } // // Geometry insertion. HOOPS can't insert a reference to a geometric object // directly, it only supports references to segments. That's why all of the // geometry insert functions return null objects. // Viewer::Object ViewerHOOPS::insertBox(float x, float y, float z) { float dx = 0.5 * x; float dy = 0.5 * y; float dz = 0.5 * z; // All the points are duplicated so the texture coords can be // set independently for each face. float pts[24][3] = { { -dx, -dy, -dz }, { -dx, -dy, dz }, { -dx, dy, dz }, { -dx, dy, -dz }, { -dx, -dy, dz }, { dx, -dy, dz }, { dx, dy, dz }, { -dx, dy, dz }, { dx, -dy, dz }, { dx, -dy, -dz }, { dx, dy, -dz }, { dx, dy, dz }, { dx, -dy, -dz }, { -dx, -dy, -dz }, { -dx, dy, -dz }, { dx, dy, -dz }, { -dx, -dy, -dz }, { dx, -dy, -dz }, { dx, -dy, dz }, { -dx, -dy, dz }, { -dx, dy, dz }, { dx, dy, dz }, { dx, dy, -dz }, { -dx, dy, -dz } }; int faces[] = { 4, 0, 1, 2, 3, 4, 4, 5, 6, 7, 4, 8, 9, 10, 11, 4, 12, 13, 14, 15, 4, 16, 17, 18, 19, 4, 20, 21, 22, 23 }; float tc[4][3] = { { 0., 0., 0. }, { 1., 0., 0. }, { 1., 1., 0. }, { 0., 1., 0. } }; long key; // We lose specularities, but it's faster. HC_Set_Rendering_Options("no lighting interpolation"); key = HC_KInsert_Shell( 24, &pts[0], 30, &faces[0]); // Texture coordinates for each face HC_MSet_Vertex_Parameters( key, 0, 4, 3, &tc[0][0]); HC_MSet_Vertex_Parameters( key, 4, 4, 3, &tc[0][0]); HC_MSet_Vertex_Parameters( key, 8, 4, 3, &tc[0][0]); HC_MSet_Vertex_Parameters( key, 12, 4, 3, &tc[0][0]); HC_MSet_Vertex_Parameters( key, 16, 4, 3, &tc[0][0]); HC_MSet_Vertex_Parameters( key, 20, 4, 3, &tc[0][0]); return 0; } // Convert -1 terminated face list to counted vertex format. // This converts the array in place, meaning that it can't be // used to render with an OpenGL-based viewer after going through here... static void convert_to_shell(int *faces, int nfaces) { int np, n; for (np=0, n = nfaces-1; n > 0; --n) { if (faces[n] == -1) // last pt of poly { if (np > 0) { faces[n+1] = np-1; } np = 0; } faces[n] = faces[n-1]; ++np; } faces[0] = np; } Viewer::Object ViewerHOOPS::insertCone(float h, float r, bool bottom, bool side) { // Build a cylinder then push all the top points together. if (side) { const int nfacets = 8; // Number of polygons for sides const int npts = 2 * nfacets; const int nfaces = nfacets * 5; float c[ npts ][ 3 ]; // coordinates float tc[ npts ][ 3 ]; // texture coordinates int faces[ nfaces ]; // face lists // should only compute tc if a texture is present... computeCylinder( h, r, nfacets, c, tc, faces); convert_to_shell( faces, nfaces); for (int i=0; i 0.0) HC_Set_Color_By_Value("ambient light", "RGB", rgb[0]*ambient, rgb[1]*ambient, rgb[2]*ambient); HC_Set_Color_By_Value( "lights", "RGB", rgb[0]*intensity, rgb[1]*intensity, rgb[2]*intensity); HC_Insert_Distant_Light( xyz[0], xyz[1], -xyz[2]); } HC_Close_Segment(); return key; } Viewer::Object ViewerHOOPS::insertElevationGrid(unsigned int mask, int nx, int nz, float *height, float dx, float dz, float *texture_coords, float *normals, float */*colors*/) { float *points = new float[nx * nz * 3]; float *p = points; float x = 0.0; for (int i=0; i 0.0 ? visibilityLimit : 200.0; float d = 0.25 * (avatarSize + zfar); float target[3], up[3]; computeView(position, orientation, d, target, up); float w = 2.0 * d * tan( 0.5 * fieldOfView ); HC_Set_Camera( position, target, up, w, w, "Perspective" ); } // Transform void ViewerHOOPS::setTransform(float * center, float * rotation, float * scale, float * scaleOrientation, float * translation) { HC_Translate_Object(-center[0], -center[1], -center[2]); if (scaleOrientation[3] != 0.0) HC_Rotate_Object_Offaxis(scaleOrientation[0], scaleOrientation[1], scaleOrientation[2], -scaleOrientation[3]*180. / M_PI); HC_Scale_Object(scale[0], scale[1], scale[2]); if (scaleOrientation[3] != 0.0) HC_Rotate_Object_Offaxis(scaleOrientation[0], scaleOrientation[1], scaleOrientation[2], scaleOrientation[3]*180. / M_PI); if (rotation[3] != 0.0) HC_Rotate_Object_Offaxis(rotation[0], rotation[1], rotation[2], rotation[3]*180. / M_PI); HC_Translate_Object(center[0], center[1], center[2]); HC_Translate_Object(translation[0], translation[1], translation[2]); } // The viewer knows the current viewpoint void ViewerHOOPS::transformPoints(int /*nPoints*/, float */*points*/) { ; } #endif // HAVE_HOOPS