Changeset 3630


Ignore:
Timestamp:
Apr 16, 2013, 3:52:20 AM (6 years ago)
Author:
ldelgass
Message:

Nanovis refactoring to fix problems with scaling and multiple results.
Do rendering in world space to properly place and scale multiple data sets.
Also fix flows to reduce resets of animations. More work toward removing
Cg dependency. Fix panning to convert viewport coords to world coords.

Location:
trunk/packages/vizservers/nanovis
Files:
85 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/nanovis/Axis.h

    r3613 r3630  
    399399                                 * the data. */
    400400
    401     double _range;              /**< Range of values on axis (max_ - min_) */
     401    double _range;              /**< Range of values on axis (_max - _min) */
    402402    double _scale;              /**< Scale factor for axis (1.0/_range) */
    403403
  • trunk/packages/vizservers/nanovis/Camera.cpp

    r3611 r3630  
    1818#include <vrmath/Vector3f.h>
    1919#include <vrmath/Vector4f.h>
     20#include <vrmath/BBox.h>
    2021
    2122#include "nanovis.h"
     
    3637}
    3738
    38 Camera::Camera(int startx, int starty, int w, int h,
    39                float loc_x, float loc_y, float loc_z) :
    40     _location(loc_x, loc_y, loc_z),
     39Camera::Camera(int x, int y, int width, int height) :
     40    _updir(Y_POS),
     41    _zoomRatio(1),
     42    _position(0, 0, 2.5),
     43    _focalPoint(0, 0, 0),
     44    _mvDirty(true),
    4145    _fov(30.0),
    4246    _near(0.1),
    43     _far(50.0),
    44     _width(w),
    45     _height(h),
    46     _startX(startx),
    47     _startY(starty)
    48 {
     47    _far(50.0)
     48{
     49    _viewport[0] = x;
     50    _viewport[1] = y;
     51    _viewport[2] = width;
     52    _viewport[3] = height;
     53    _pan[0] = 0;
     54    _pan[1] = 0;
    4955}
    5056
    5157void
    52 Camera::getUpDirMatrix(Matrix4x4d& upMat)
    53 {
    54     switch (NanoVis::updir) {
    55     case NanoVis::X_POS: {
    56         upMat.makeRotation(0, 0, 1, deg2rad(90));
     58Camera::pan(float x, float y, bool absolute)
     59{
     60    y = -y;
     61    if (absolute) {
     62        double panAbs[2];
     63        panAbs[0] = x;
     64        panAbs[1] = y;
     65        x -= _pan[0];
     66        y -= _pan[1];
     67        _pan[0] = panAbs[0];
     68        _pan[1] = panAbs[1];
     69    } else {
     70        _pan[0] += x;
     71        _pan[1] += y;
     72    }
     73
     74    if (x != 0.0 || y != 0.0) {
     75        Vector3f worldFocalPoint;
     76        worldToWindowCoords(_focalPoint.x, _focalPoint.y, _focalPoint.z,
     77                            worldFocalPoint);
     78        float focalDepth = worldFocalPoint.z;
     79
     80        Vector3f newPickPoint, oldPickPoint, motionVector;
     81        windowToWorldCoords((x * 2. + 1.) * (float)_viewport[2] / 2.0,
     82                            (y * 2. + 1.) * (float)_viewport[3] / 2.0,
     83                            focalDepth,
     84                            newPickPoint);
     85
     86        windowToWorldCoords((float)_viewport[2] / 2.0,
     87                            (float)_viewport[3] / 2.0,
     88                            focalDepth,
     89                            oldPickPoint);
     90
     91        // Camera motion is reversed
     92        motionVector = oldPickPoint - newPickPoint;
     93
     94        _focalPoint += motionVector;
     95        _position += motionVector;
     96
     97        _mvDirty = true;
     98    }
     99}
     100
     101void
     102Camera::zoom(float z, bool absolute)
     103{
     104    if (absolute) {
     105        // Compute relative zoom
     106        float zAbs = z;
     107        z *= 1.0/_zoomRatio;
     108        _zoomRatio = zAbs;
     109    } else {
     110        _zoomRatio *= z;
     111    }
     112    float distance = getDistance() / z;
     113    Vector3f dir = getViewPlaneNormal();
     114    dir = dir.scale(distance);
     115    _position = _focalPoint + dir;
     116    _mvDirty = true;
     117}
     118
     119const Matrix4x4d&
     120Camera::getUpDirMatrix() const
     121{
     122    return _updirMatrix;
     123}
     124
     125void
     126Camera::setUpDirMatrix(AxisDirection dir)
     127{
     128    _updir = dir;
     129
     130    switch (_updir) {
     131    case X_POS: {
     132        _updirMatrix.makeRotation(0, 0, 1, deg2rad(90));
    57133        Matrix4x4d tmp;
    58134        tmp.makeRotation(1, 0, 0, deg2rad(90));
    59         upMat.multiply(tmp);
    60     }
    61         break;
    62     case NanoVis::Y_POS:
    63         upMat.makeIdentity();
    64         break;
    65     case NanoVis::Z_POS: {
    66         upMat.makeRotation(1, 0, 0, deg2rad(-90));
     135        _updirMatrix.multiply(tmp);
     136    }
     137        break;
     138    case Y_POS:
     139        _updirMatrix.makeIdentity();
     140        break;
     141    case Z_POS: {
     142        _updirMatrix.makeRotation(1, 0, 0, deg2rad(-90));
    67143        Matrix4x4d tmp;
    68144        tmp.makeRotation(0, 0, 1, deg2rad(-90));
    69         upMat.multiply(tmp);
    70     }
    71         break;
    72     case NanoVis::X_NEG:
    73         upMat.makeRotation(0, 0, 1, deg2rad(-90));
    74         break;
    75     case NanoVis::Y_NEG: {
    76         upMat.makeRotation(0, 0, 1, deg2rad(180));
     145        _updirMatrix.multiply(tmp);
     146    }
     147        break;
     148    case X_NEG:
     149        _updirMatrix.makeRotation(0, 0, 1, deg2rad(-90));
     150        break;
     151    case Y_NEG: {
     152        _updirMatrix.makeRotation(0, 0, 1, deg2rad(180));
    77153        Matrix4x4d tmp;
    78154        tmp.makeRotation(0, 1, 0, deg2rad(-90));
    79         upMat.multiply(tmp);
    80     }
    81         break;
    82     case NanoVis::Z_NEG:
    83         upMat.makeRotation(1, 0, 0, deg2rad(90));
     155        _updirMatrix.multiply(tmp);
     156    }
     157        break;
     158    case Z_NEG:
     159        _updirMatrix.makeRotation(1, 0, 0, deg2rad(90));
    84160        break;
    85161    }
     
    97173
    98174    if (resetOrientation) {
    99         _cameraMatrix.makeIdentity();
    100     }
    101 
    102     Vector3f center(bboxMin + bboxMax);
    103     center.scale(0.5);
    104 
    105     Matrix4x4d mat, upMat;
    106     getUpDirMatrix(upMat);
    107     mat.makeTranslation(-center);
    108     mat.multiply(_cameraMatrix, mat);
    109     mat.multiply(upMat);
    110 
    111     Vector3f emin(FLT_MAX, FLT_MAX, FLT_MAX), emax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    112 
    113     // Transform bounds by camera matrix
    114     Vector4f bboxEye[8];
    115     bboxEye[0] = Vector4f(bboxMin.x, bboxMin.y, bboxMin.z, 1);
    116     bboxEye[1] = Vector4f(bboxMax.x, bboxMin.y, bboxMin.z, 1);
    117     bboxEye[2] = Vector4f(bboxMin.x, bboxMax.y, bboxMin.z, 1);
    118     bboxEye[3] = Vector4f(bboxMin.x, bboxMin.y, bboxMax.z, 1);
    119     bboxEye[4] = Vector4f(bboxMax.x, bboxMax.y, bboxMin.z, 1);
    120     bboxEye[5] = Vector4f(bboxMax.x, bboxMin.y, bboxMax.z, 1);
    121     bboxEye[6] = Vector4f(bboxMin.x, bboxMax.y, bboxMax.z, 1);
    122     bboxEye[7] = Vector4f(bboxMax.x, bboxMax.y, bboxMax.z, 1);
    123 
    124     for (int i = 0; i < 8; i++) {
    125         Vector4f eyeVert = mat.transform(bboxEye[i]);
    126         if (eyeVert.x < emin.x) emin.x = eyeVert.x;
    127         if (eyeVert.x > emax.x) emax.x = eyeVert.x;
    128         if (eyeVert.y < emin.y) emin.y = eyeVert.y;
    129         if (eyeVert.y > emax.y) emax.y = eyeVert.y;
    130         if (eyeVert.z < emin.z) emin.z = eyeVert.z;
    131         if (eyeVert.z > emax.z) emax.z = eyeVert.z;
    132     }
     175        _rotationMatrix.makeIdentity();
     176    }
     177
     178    BBox bbox(bboxMin, bboxMax);
     179    Vector3f center = bbox.getCenter();
     180    _focalPoint.set(center.x, center.y, center.z);
     181
     182    Matrix4x4d mat;
     183    mat.makeTranslation(-_focalPoint);
     184    mat.multiply(_updirMatrix, mat); // premult
     185    mat.multiply(_rotationMatrix, mat); // premult
     186
     187    bbox.transform(bbox, mat);
     188
     189    Vector3f emin = bbox.min;
     190    Vector3f emax = bbox.max;
    133191
    134192    TRACE("Eye bounds: (%g,%g,%g) - (%g,%g,%g)",
     
    146204
    147205    // Deal with vertical aspect window
    148     double winAspect = (double)(_width - _startX)/(double)(_height - _startY);
     206    double winAspect = (double)_viewport[2]/(double)_viewport[3];
    149207    double sceneAspect = 1.0;;
    150208    if (bheight > 0.0)
     
    161219    _far = _near + bdepth;
    162220
    163     _location.set(center.x, center.y, center.z + distance);
     221    Vector3f viewPlaneNormal(0, 0, 1);
     222    mat.transpose();
     223    viewPlaneNormal = mat.transformVec(viewPlaneNormal);
     224    _position = _focalPoint + viewPlaneNormal * distance;
    164225
    165226    TRACE("win aspect: %g scene aspect: %g", winAspect, sceneAspect);
     227    TRACE("vpn: %g, %g, %g", viewPlaneNormal.x, viewPlaneNormal.y, viewPlaneNormal.z);
    166228    TRACE("c: %g,%g,%g, d: %g", center.x, center.y, center.z, distance);
     229    TRACE("pos: %g, %g, %g", _position.x, _position.y, _position.z);
    167230    TRACE("near: %g, far: %g", _near, _far);
     231
     232    _zoomRatio = 1.0;
     233    _pan[0] = 0;
     234    _pan[1] = 0;
     235    _mvDirty = true;
    168236
    169237    initialize();
     
    171239}
    172240
     241/**
     242 * \brief Reset near and far planes based on given world space
     243 * bounding box
     244 *
     245 * This method is based on VTK's renderer class implementation
     246 * The idea is to plug the bounding box corners into the view
     247 * plane equation to find the min and max distance of the scene
     248 * to the view plane.
     249 */
    173250void
    174251Camera::resetClippingRange(const Vector3f& bboxMin, const Vector3f& bboxMax)
    175252{
    176     Vector3f emin(bboxMin.x, bboxMin.y, bboxMin.z), emax(bboxMax.x, bboxMax.y, bboxMax.z);
    177 
    178     Vector3f center(emin + emax);
    179     center.scale(0.5);
    180 
    181     // Compute the radius of the enclosing sphere,
    182     // which is half the bounding box diagonal
    183     Vector3f diagonal(emax - emin);
    184     double radius = diagonal.length() * 0.5;
    185 
    186     // If we have just a single point, pick a radius of 1.0
    187     radius = (radius == 0) ? 1.0 : radius;
    188 
    189     TRACE("c: %g,%g,%g, r: %g cam z: %g", center.x, center.y, center.z, radius, _location.z);
    190 
    191     _near = _location.z - radius;
    192     _far = _location.z + radius;
    193 
    194     if (_near < 0.0) {
    195         _near = 0.001;
    196     }
    197     if (_far < 0.0) {
    198         _far = 1.0;
    199     }
     253    BBox bbox(bboxMin, bboxMax);
     254
     255    // Set up view plane equation at camera position
     256    Vector3f vpn = getViewPlaneNormal();
     257    double a, b, c, d, dist;
     258    a = -vpn.x;
     259    b = -vpn.y;
     260    c = -vpn.z;
     261    d = -(a*_position.x + b*_position.y + c*_position.z);
     262
     263    // Now compute distance of bounding box corners to view plane
     264
     265    // Set starting limits
     266    _near = a * bbox.min.x + b * bbox.min.y + c * bbox.min.z + d;
     267    _far = 1e-18;
     268
     269    // Iterate over the 8 bbox corners
     270    for (int k = 0; k < 2; k++) {
     271        for (int j = 0; j < 2; j++) {
     272            for (int i = 0; i < 2; i++) {
     273                dist =
     274                    (a * ((i == 0) ? bbox.min.x : bbox.max.x)) +
     275                    (b * ((j == 0) ? bbox.min.y : bbox.max.y)) +
     276                    (c * ((k == 0) ? bbox.min.z : bbox.max.z)) + d;
     277                _near = (dist < _near) ? dist : _near;
     278                _far =  (dist > _far)  ? dist : _far;
     279            }
     280        }
     281    }
     282
     283    // Check for near plane behind the camera
     284    if (_near < 0) {
     285        _near = 0;
     286    }
     287
     288    // Extend the bounds a bit
     289    _near = 0.99 * _near - (_far - _near) * 0.5;
     290    _far  = 1.01 * _far  + (_far - _near) * 0.5;
     291
     292    // Ensure near is closer than far
     293    _near = (_near >= _far) ? (0.01 * _far) : _near;
     294
     295    // Limit clip range to make best use of z buffer precision
     296    if (_near < .001 * _far)
     297        _near = .001 * _far;
    200298
    201299    TRACE("Resetting camera clipping range to: near: %g, far: %g", _near, _far);
     
    204302    glLoadIdentity();
    205303    gluPerspective(_fov,
    206                    (GLdouble)(_width - _startX)/(GLdouble)(_height - _startY),
     304                   (GLdouble)_viewport[2]/(GLdouble)_viewport[3],
    207305                   _near, _far);
    208306    glMatrixMode(GL_MODELVIEW);
     
    217315    print();
    218316
    219     glViewport(_startX, _startY, _width, _height);
     317    glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
    220318    glMatrixMode(GL_PROJECTION);
    221319    glLoadIdentity();
    222320    gluPerspective(_fov,
    223                    (GLdouble)(_width - _startX)/(GLdouble)(_height - _startY),
     321                   (GLdouble)_viewport[2]/(GLdouble)_viewport[3],
    224322                   _near, _far);
    225323
    226324    glMatrixMode(GL_MODELVIEW);
     325
     326    computeModelViewMatrix();
     327    glLoadMatrixd((const GLdouble *)_modelViewMatrix.get());
     328}
     329
     330void Camera::windowToWorldCoords(double x, double y, double z, Vector3f& objPos)
     331{
     332    Matrix4x4d proj;
     333    getProjectionMatrix(proj);
     334    GLdouble outX, outY, outZ;
     335    gluUnProject(x, y, z,
     336                 (GLdouble *)getModelViewMatrix().get(),
     337                 (GLdouble *)proj.get(),
     338                 (GLint *)_viewport,
     339                 &outX, &outY, &outZ);
     340    objPos.set(outX, outY, outZ);
     341}
     342
     343void Camera::worldToWindowCoords(double x, double y, double z, Vector3f& winPos)
     344{
     345    Matrix4x4d proj;
     346    getProjectionMatrix(proj);
     347    GLdouble outX, outY, outZ;
     348    gluProject(x, y, z,
     349               (GLdouble *)getModelViewMatrix().get(),
     350               (GLdouble *)proj.get(),
     351               (GLint *)_viewport,
     352               &outX, &outY, &outZ);
     353    winPos.set(outX, outY, outZ);
     354}
     355
     356void Camera::computeModelViewMatrix()
     357{
     358    if (_mvDirty) {
     359        _modelViewMatrix.makeTranslation(0, 0, -getDistance());
     360        _modelViewMatrix.multiply(_rotationMatrix);
     361        _modelViewMatrix.multiply(_updirMatrix);
     362        Matrix4x4d mat;
     363        mat.makeTranslation(-_focalPoint);
     364        _modelViewMatrix.multiply(mat);
     365        _mvDirty = false;
     366    }
     367}
     368
     369void Camera::getProjectionMatrix(Matrix4x4d& mat)
     370{
     371    glMatrixMode(GL_PROJECTION);
     372    glPushMatrix();
    227373    glLoadIdentity();
    228 
    229     glTranslatef(-_location.x, -_location.y, -_location.z);
    230     glMultMatrixd((const GLdouble *)_cameraMatrix.get());
    231 }
    232 
    233 void Camera::rotate(double *quat)
     374    gluPerspective(_fov,
     375                   (GLdouble)_viewport[2]/(GLdouble)_viewport[3],
     376                   _near, _far);
     377    glGetDoublev(GL_PROJECTION_MATRIX, (GLdouble *)mat.get());
     378    glPopMatrix();
     379    glMatrixMode(GL_MODELVIEW);
     380}
     381
     382void Camera::orient(double *quat)
    234383{
    235384    Quaternion q(quat[0], quat[1], quat[2], quat[3]);
    236385    Rotation rot;
    237386    rot.set(q);
    238     _cameraMatrix.makeRotation(rot);
    239     _cameraMatrix.transpose();
     387    _rotationMatrix.makeRotation(rot);
     388    _rotationMatrix.transpose();
     389    _mvDirty = true;
     390    computeModelViewMatrix();
     391
     392    Vector3f viewPlaneNormal(0, 0, 1);
     393    Matrix4x4d mat = getModelViewMatrix();
     394    mat.transpose();
     395    viewPlaneNormal = mat.transformVec(viewPlaneNormal);
     396    TRACE("vpn: %g %g %g", viewPlaneNormal.x, viewPlaneNormal.y, viewPlaneNormal.z);
     397    _position = _focalPoint + viewPlaneNormal * getDistance();
     398
    240399    TRACE("Set rotation to quat: %g %g %g %g",
    241400          quat[0], quat[1], quat[2], quat[3]);
    242401}
    243402
    244 void Camera::rotate(float angleX, float angleY, float angleZ)
     403void Camera::orient(float angleX, float angleY, float angleZ)
    245404{
    246405    angleX = -angleX;
    247406    angleY = angleY - 180.;
    248407
    249     _cameraMatrix.makeRotation(1, 0, 0, deg2rad(angleX));
     408    _rotationMatrix.makeRotation(1, 0, 0, deg2rad(angleX));
    250409    Matrix4x4d mat;
    251410    mat.makeRotation(0, 1, 0, deg2rad(angleY));
    252     _cameraMatrix.multiply(mat);
     411    _rotationMatrix.multiply(mat);
    253412    mat.makeRotation(0, 0, 1, deg2rad(angleZ));
    254     _cameraMatrix.multiply(mat);
    255     //_cameraMatrix.transpose();
     413    _rotationMatrix.multiply(mat);
     414    _mvDirty = true;
     415    computeModelViewMatrix();
     416
     417    Vector3f viewPlaneNormal(0, 0, 1);
     418    mat = getModelViewMatrix();
     419    mat.transpose();
     420    viewPlaneNormal = mat.transformVec(viewPlaneNormal);
     421    TRACE("vpn: %g %g %g", viewPlaneNormal.x, viewPlaneNormal.y, viewPlaneNormal.z);
     422    _position = _focalPoint + viewPlaneNormal * getDistance();
    256423
    257424    TRACE("Set rotation to angles: %g %g %g",
     
    261428void Camera::print() const
    262429{
    263     TRACE("x: %d y: %d w: %d h: %d", _startX, _startY, _width, _height);
    264     TRACE("loc: %g %g %g",
    265           _location.x, _location.y, _location.z);
    266     TRACE("Camera matrix: ");
    267     _cameraMatrix.print();
     430    TRACE("x: %d y: %d w: %d h: %d",
     431          _viewport[0], _viewport[1], _viewport[2], _viewport[3]);
    268432    TRACE("fov: %g near: %g far: %g", _fov, _near, _far);
    269 }
     433    TRACE("fp: %g, %g, %g",
     434          _focalPoint.x, _focalPoint.y, _focalPoint.z);
     435    TRACE("pos: %g, %g, %g",
     436          _position.x, _position.y, _position.z);
     437    TRACE("Rotation matrix: ");
     438    _rotationMatrix.print();
     439    TRACE("Modelview matrix: ");
     440    _modelViewMatrix.print();
     441}
  • trunk/packages/vizservers/nanovis/Camera.h

    r3611 r3630  
    1919{
    2020public:
    21     Camera(int startx, int starty, int w, int h,
    22              float loc_x, float loc_y, float loc_z);
     21    enum AxisDirection {
     22        X_POS = 1,
     23        Y_POS = 2,
     24        Z_POS = 3,
     25        X_NEG = -1,
     26        Y_NEG = -2,
     27        Z_NEG = -3
     28    };
     29
     30    Camera(int x, int y, int width, int height);
    2331
    2432    ~Camera()
    2533    {}
    2634
    27     //move location of camera
    28     void x(float loc_x)
     35    void setUpdir(AxisDirection dir)
    2936    {
    30         _location.x = loc_x;
     37         setUpDirMatrix(dir);
     38        _mvDirty = true;
    3139    }
    3240
    33     float x() const
     41    void setPosition(const vrmath::Vector3f& pos)
    3442    {
    35         return _location.x;
     43        _position = pos;
     44        _mvDirty = true;
    3645    }
    3746
    38     void y(float loc_y)
     47    const vrmath::Vector3f& getPosition() const
    3948    {
    40         _location.y = loc_y;
     49        return _position;
    4150    }
    4251
    43     float y() const
     52    const vrmath::Vector3f& getFocalPoint() const
    4453    {
    45         return _location.y;
     54        return _focalPoint;
    4655    }
    4756
    48     void z(float loc_z)
     57    float getDistance() const
    4958    {
    50         _location.z = loc_z;
     59        return vrmath::Vector3f(_focalPoint - _position).length();
    5160    }
    5261
    53     float z() const
     62    vrmath::Vector3f getDirectionOfProjection() const
    5463    {
    55         return _location.z;
     64        vrmath::Vector3f dir = _focalPoint - _position;
     65        dir = dir.normalize();
     66        return dir;
    5667    }
    5768
    58     void rotate(double *quat);
     69    vrmath::Vector3f getViewPlaneNormal() const
     70    {
     71        vrmath::Vector3f dir = _position - _focalPoint;
     72        dir = dir.normalize();
     73        return dir;
     74    }
    5975
    60     void rotate(float angle_x, float angle_y, float angle_z);
     76    void pan(float x, float y, bool absolute = true);
    6177
    62     void fov(float fov)
     78    void zoom(float z, bool absolute = true);
     79
     80    void orient(double *quat);
     81
     82    void orient(float angleX, float angleY, float angleZ);
     83
     84    void setFov(float fov)
    6385    {
    6486        _fov = fov;
    6587    }
    6688
    67     float fov() const
     89    float getFov() const
    6890    {
    6991        return _fov;
     
    7496               bool resetOrientation = false);
    7597
    76     void setClippingRange(float near, float far)
    77     {
    78         _near = near;
    79         _far = far;
    80     }
    81 
    8298    void resetClippingRange(const vrmath::Vector3f& bboxMin,
    8399                            const vrmath::Vector3f& bboxMax);
    84100
    85     void setScreenSize(int sx, int sy, int w, int h)
     101    void setViewport(int x, int y, int width, int height)
    86102    {
    87         _width = w;
    88         _height = h;
    89         _startX = sx;
    90         _startY = sy;
     103        _viewport[0] = x;
     104        _viewport[1] = y;
     105        _viewport[2] = width;
     106        _viewport[3] = height;
    91107    }
    92108
     
    99115    void print() const;
    100116
     117    vrmath::Matrix4x4d& getModelViewMatrix()
     118    {
     119        computeModelViewMatrix();
     120        return _modelViewMatrix;
     121    }
     122
     123    void getProjectionMatrix(vrmath::Matrix4x4d& mat);
     124
     125    const vrmath::Matrix4x4d& getUpDirMatrix() const;
     126
     127    void windowToWorldCoords(double x, double y, double z, vrmath::Vector3f& objPos);
     128
     129    void worldToWindowCoords(double x, double y, double z, vrmath::Vector3f& winPos);
     130
    101131private:
    102     void getUpDirMatrix(vrmath::Matrix4x4d& upMat);
     132    void computeModelViewMatrix();
    103133
    104     /// Location of the camera in the scene
    105     vrmath::Vector3f _location;
    106     /// Camera view matrix (orientation only, no translation)
    107     vrmath::Matrix4x4d _cameraMatrix;
     134    void setUpDirMatrix(AxisDirection dir);
     135
     136    AxisDirection _updir;
     137
     138    double _zoomRatio;
     139    float _pan[2];
     140    /// Position of the camera in the scene
     141    vrmath::Vector3f _position;
     142    vrmath::Vector3f _focalPoint;
     143
     144    /// Model transform for z-up scene
     145    vrmath::Matrix4x4d _updirMatrix;
     146    /// Camera orientation
     147    vrmath::Matrix4x4d _rotationMatrix;
     148    /// Full camera matrix
     149    bool _mvDirty;
     150    vrmath::Matrix4x4d _modelViewMatrix;
     151
    108152    /// Field of view (vertical angle in degrees)
    109153    float _fov;
     
    111155    float _near, _far;
    112156
    113     /// screen width
    114     int _width;
    115     /// screen height
    116     int _height;
    117     int _startX;
    118     int _startY;
    119 };
     157    // x, y, width, height
     158    int _viewport[4];
     159 };
    120160
    121161}
  • trunk/packages/vizservers/nanovis/ColorTableShader.cpp

    r3612 r3630  
    1919void ColorTableShader::init()
    2020{
    21     loadFragmentProgram("one_plane.cg", "main");
     21    loadFragmentProgram("one_plane.cg");
    2222}
    2323
  • trunk/packages/vizservers/nanovis/Command.cpp

    r3611 r3630  
    568568        return TCL_ERROR;
    569569    }
    570     NanoVis::cam->rotate(phi, theta, psi);
    571     return TCL_OK;
     570    //NanoVis::orientCamera(phi, theta, psi);
     571    //return TCL_OK;
     572    Tcl_AppendResult(interp, "The 'camera angle' command is deprecated, use 'camera orient'", (char*)NULL);
     573    return TCL_ERROR;
    572574}
    573575
     
    583585        return TCL_ERROR;
    584586    }
    585     NanoVis::cam->rotate(quat);
     587    NanoVis::orientCamera(quat);
    586588    return TCL_OK;
    587589}
     
    596598        return TCL_ERROR;
    597599    }
    598     NanoVis::pan(x, y);
     600    NanoVis::panCamera(x, y);
    599601    return TCL_OK;
    600602}
     
    604606                 Tcl_Obj *const *objv)
    605607{
    606     float x, y, z;
    607     if ((GetFloatFromObj(interp, objv[2], &x) != TCL_OK) ||
    608         (GetFloatFromObj(interp, objv[3], &y) != TCL_OK) ||
    609         (GetFloatFromObj(interp, objv[4], &z) != TCL_OK)) {
    610         return TCL_ERROR;
    611     }
    612     NanoVis::cam->x(x);
    613     NanoVis::cam->y(y);
    614     NanoVis::cam->z(z);
     608    Vector3f pos;
     609    if ((GetFloatFromObj(interp, objv[2], &pos.x) != TCL_OK) ||
     610        (GetFloatFromObj(interp, objv[3], &pos.y) != TCL_OK) ||
     611        (GetFloatFromObj(interp, objv[4], &pos.z) != TCL_OK)) {
     612        return TCL_ERROR;
     613    }
     614
     615    NanoVis::setCameraPosition(pos);
    615616    return TCL_OK;
    616617}
     
    643644        return TCL_ERROR;
    644645    }
    645     NanoVis::zoom(z);
     646    NanoVis::zoomCamera(z);
    646647    return TCL_OK;
    647648}
     
    725726    std::vector<Volume *>::iterator iter;
    726727    for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    727         (*iter)->moveCutplane(axis, relval);
    728     }
    729     return TCL_OK;
    730 }
    731 
    732 /*
    733  * cutplane state $bool $axis vol,,,
    734  */
     728        (*iter)->setCutplanePosition(axis, relval);
     729    }
     730    return TCL_OK;
     731}
     732
    735733static int
    736734CutplaneStateOp(ClientData clientData, Tcl_Interp *interp, int objc,
     
    11231121        return TCL_ERROR;
    11241122    }
    1125     NanoVis::updir = (axis+1)*sign;
     1123    NanoVis::setCameraUpdir(Camera::AxisDirection((axis+1)*sign));
    11261124    return TCL_OK;
    11271125}
     
    12641262        }
    12651263        TRACE("finish loading");
    1266 
    1267         Vector3f scale = volume->getPhysicalScaling();
    1268         Vector3f loc(scale);
    1269         loc *= -0.5;
    1270         volume->location(loc);
    12711264
    12721265        NanoVis::VolumeHashmap::iterator itr = NanoVis::volumeTable.find(tag);
  • trunk/packages/vizservers/nanovis/Flow.cpp

    r3611 r3630  
    1010 */
    1111
     12#include <float.h>
     13
    1214#include <tcl.h>
    1315
     16#include <vrmath/BBox.h>
    1417#include <vrmath/Vector3f.h>
    1518
     
    3134using namespace vrmath;
    3235
     36bool Flow::updatePending = false;
     37double Flow::magMin = DBL_MAX;
     38double Flow::magMax = -DBL_MAX;
     39
    3340Flow::Flow(Tcl_Interp *interp, const char *name) :
    3441    _interp(interp),
     
    8188        return;
    8289
    83 #if 0  // Using volume bounds instead of these
     90    BBox allBounds;
    8491    if (isDataLoaded()) {
    85         Vector3f umin, umax;
    86         Rappture::Unirect3d *unirect = data();
    87         unirect->getWorldSpaceBounds(umin, umax);
    88         if (min.x > umin.x) {
    89             min.x = umin.x;
    90         }
    91         if (max.x < umax.x) {
    92             max.x = umax.x;
    93         }
    94         if (min.y > umin.y) {
    95             min.y = umin.y;
    96         }
    97         if (max.y < umax.y) {
    98             max.y = umax.y;
    99         }
    100         if (min.z > umin.z) {
    101             min.z = umin.z;
    102         }
    103         if (max.z < umax.z) {
    104             max.z = umax.z;
    105         }
    106     }
    107 #endif
     92        BBox bbox;
     93        data()->getBounds(bbox.min, bbox.max);
     94        allBounds.extend(bbox);
     95    }
    10896    for (BoxHashmap::iterator itr = _boxTable.begin();
    10997         itr != _boxTable.end(); ++itr) {
    11098        FlowBox *box = itr->second;
    11199        if (!onlyVisible || box->visible()) {
    112             Vector3f fbmin, fbmax;
    113             box->getWorldSpaceBounds(fbmin, fbmax,
    114                                      getVolume());
    115             if (min.x > fbmin.x) {
    116                 min.x = fbmin.x;
    117             }
    118             if (max.x < fbmax.x) {
    119                 max.x = fbmax.x;
    120             }
    121             if (min.y > fbmin.y) {
    122                 min.y = fbmin.y;
    123             }
    124             if (max.y < fbmax.y) {
    125                 max.y = fbmax.y;
    126             }
    127             if (min.z > fbmin.z) {
    128                 min.z = fbmin.z;
    129             }
    130             if (max.z < fbmax.z) {
    131                 max.z = fbmax.z;
    132             }
    133         }
    134     }
     100            BBox bbox;
     101            box->getBounds(bbox.min, bbox.max);
     102            allBounds.extend(bbox);
     103        }
     104    }
     105    min = allBounds.min;
     106    max = allBounds.max;
    135107}
    136108
     
    143115    switch (position->axis) {
    144116    case AXIS_X: 
    145         return (position->value - NanoVis::xMin) /
    146             (NanoVis::xMax - NanoVis::xMin);
     117        return (position->value - _data->xMin()) /
     118            (_data->xMax() - _data->xMin());
    147119    case AXIS_Y: 
    148         return (position->value - NanoVis::yMin) /
    149             (NanoVis::yMax - NanoVis::yMin);
     120        return (position->value - _data->yMin()) /
     121            (_data->yMax() - _data->yMin());
    150122    case AXIS_Z: 
    151         return (position->value - NanoVis::zMin) /
    152             (NanoVis::zMax - NanoVis::zMin);
     123        return (position->value - _data->zMin()) /
     124            (_data->zMax() - _data->zMin());
    153125    }
    154126    return 0.0;
    155 }
    156 
    157 float
    158 Flow::getRelativePosition()
    159 {
    160     return getRelativePosition(&_sv.slicePos);
    161127}
    162128
     
    295261
    296262bool
     263Flow::configure()
     264{
     265    bool needReset = false;
     266
     267    if (_volume != NULL) {
     268        _volume->transferFunction(_sv.transferFunction);
     269        _volume->dataEnabled(_sv.showVolume);
     270        _volume->twoSidedLighting(_sv.twoSidedLighting);
     271        _volume->outline(_sv.showOutline);
     272        _volume->opacityScale(_sv.opacity);
     273        _volume->ambient(_sv.ambient);
     274        _volume->diffuse(_sv.diffuse);
     275        _volume->specularLevel(_sv.specular);
     276        _volume->specularExponent(_sv.specularExp);
     277    }
     278
     279    float slicePos = getRelativePosition(&_sv.slicePos);
     280
     281    // FIXME: LIC and arrows should be per-flow
     282    if (NanoVis::licRenderer != NULL) {
     283        if (NanoVis::licRenderer->getSliceAxis() != _sv.slicePos.axis) {
     284            needReset = true;
     285            NanoVis::licRenderer->setSliceAxis(_sv.slicePos.axis);
     286        }
     287        if (NanoVis::licRenderer->getSlicePosition() != slicePos) {
     288            needReset = true;
     289            NanoVis::licRenderer->setSlicePosition(slicePos);
     290        }
     291        NanoVis::licRenderer->visible(_sv.sliceVisible);
     292    }
     293    if (NanoVis::velocityArrowsSlice != NULL) {
     294        NanoVis::velocityArrowsSlice->setSliceAxis(_sv.slicePos.axis);
     295        NanoVis::velocityArrowsSlice->setSlicePosition(slicePos);
     296        NanoVis::velocityArrowsSlice->visible(_sv.showArrows);
     297    }
     298
     299    return needReset;
     300}
     301
     302bool
    297303Flow::scaleVectorField()
    298304{
     305    float *vdata = getScaledVector();
    299306    if (_volume != NULL) {
    300         TRACE("Removing existing volume: %s", _volume->name());
    301         NanoVis::removeVolume(_volume);
    302         _volume = NULL;
    303     }
    304     float *vdata = getScaledVector();
    305     if (vdata == NULL) {
    306         return false;
    307     }
    308     Volume *volume = makeVolume(vdata);
     307        TRACE("Updating existing volume: %s", _volume->name());
     308        _volume->setData(vdata, magMin, magMax, 0);
     309    } else {
     310        _volume = makeVolume(vdata);
     311        if (_volume == NULL) {
     312            return false;
     313        }
     314    }
    309315    delete [] vdata;
    310     if (volume == NULL) {
    311         return false;
    312     }
    313     _volume = volume;
    314 
    315     Vector3f scale = volume->getPhysicalScaling();
    316     Vector3f location = _volume->location();
    317 
     316    // FIXME: LIC and arrows should be per-flow
    318317    if (NanoVis::licRenderer != NULL) {
    319         NanoVis::licRenderer->
    320             setVectorField(_volume->textureID(),
    321                            location,
    322                            scale.x,
    323                            scale.y,
    324                            scale.z,
    325                            _volume->wAxis.max());
    326         setCurrentPosition();
    327         setAxis();
    328         setActive();
    329     }
    330 
     318        NanoVis::licRenderer->setVectorField(_volume);
     319        NanoVis::licRenderer->setSliceAxis(_sv.slicePos.axis);
     320        NanoVis::licRenderer->setSlicePosition(getRelativePosition(&_sv.slicePos));
     321        NanoVis::licRenderer->visible(_sv.sliceVisible);
     322    }
    331323    if (NanoVis::velocityArrowsSlice != NULL) {
    332         NanoVis::velocityArrowsSlice->
    333             setVectorField(_volume->textureID(),
    334                            location,
    335                            scale.x,
    336                            scale.y,
    337                            scale.z,
    338                            _volume->wAxis.max());
    339         NanoVis::velocityArrowsSlice->axis(_sv.slicePos.axis);
    340         NanoVis::velocityArrowsSlice->slicePos(_sv.slicePos.value);
    341         NanoVis::velocityArrowsSlice->enabled(_sv.showArrows);
    342     }
    343 
    344     for (ParticlesHashmap::iterator itr = _particlesTable.begin();
    345          itr != _particlesTable.end(); ++itr) {
    346         itr->second->setVectorField(_volume,
    347                                     location,
    348                                     scale.x,
    349                                     scale.y,
    350                                     scale.z,
    351                                     _volume->wAxis.max());
     324        NanoVis::velocityArrowsSlice->setVectorField(_volume);
     325        NanoVis::velocityArrowsSlice->setSliceAxis(_sv.slicePos.axis);
     326        NanoVis::velocityArrowsSlice->setSlicePosition(getRelativePosition(&_sv.slicePos));
     327        NanoVis::velocityArrowsSlice->visible(_sv.showArrows);
     328    }
     329    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
     330         itr != _particlesTable.end(); ++itr) {
     331        itr->second->setVectorField(_volume);
    352332    }
    353333    return true;
     
    371351    size_t n = _data->nValues() / _data->nComponents() * 4;
    372352    float *data = new float[n];
    373     if (data == NULL) {
    374         return NULL;
    375     }
    376353    memset(data, 0, sizeof(float) * n);
    377354    float *dest = data;
     
    385362                vz = values[2];
    386363                vm = sqrt(vx*vx + vy*vy + vz*vz);
    387                 dest[0] = vm / NanoVis::magMax;
    388                 dest[1] = vx /(2.0*NanoVis::magMax) + 0.5;
    389                 dest[2] = vy /(2.0*NanoVis::magMax) + 0.5;
    390                 dest[3] = vz /(2.0*NanoVis::magMax) + 0.5;
     364                dest[0] = vm / magMax;
     365                dest[1] = vx /(2.0 * magMax) + 0.5;
     366                dest[2] = vy /(2.0 * magMax) + 0.5;
     367                dest[3] = vz /(2.0 * magMax) + 0.5;
    391368                values += 3;
    392369                dest += 4;
     
    406383                            _data->zNum(),
    407384                            4, data,
    408                             NanoVis::magMin, NanoVis::magMax, 0);
     385                            magMin, magMax, 0);
    409386    volume->xAxis.setRange(_data->xMin(), _data->xMax());
    410387    volume->yAxis.setRange(_data->yMin(), _data->yMax());
    411388    volume->zAxis.setRange(_data->zMin(), _data->zMax());
    412389
    413     TRACE("min=%g %g %g max=%g %g %g mag=%g %g",
    414           NanoVis::xMin, NanoVis::yMin, NanoVis::zMin,
    415           NanoVis::xMax, NanoVis::yMax, NanoVis::zMax,
    416           NanoVis::magMin, NanoVis::magMax);
     390    TRACE("mag=%g %g", magMin, magMax);
    417391
    418392    volume->disableCutplane(0);
     
    430404    volume->specularLevel(_sv.specular);
    431405    volume->specularExponent(_sv.specularExp);
    432     volume->visible(_sv.showVolume);
    433 
    434     Vector3f volScaling = volume->getPhysicalScaling();
    435     Vector3f loc(volScaling);
    436     loc *= -0.5;
    437     volume->location(loc);
    438406
    439407    Volume::updatePending = true;
  • trunk/packages/vizservers/nanovis/Flow.h

    r3613 r3630  
    2525#include "FlowBox.h"
    2626#include "LIC.h"
     27#include "VelocityArrowsSlice.h"
    2728#include "Unirect.h"
    2829#include "Volume.h"
     
    5051{
    5152public:
    52     enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
    53 
    5453    Flow(Tcl_Interp *interp, const char *name);
    5554
     
    8483    void getBoxNames(std::vector<std::string>& names);
    8584
    86     float *getScaledVector();
    87 
    88     Volume *makeVolume(float *data);
    89 
    9085    bool scaleVectorField();
    9186
     
    117112        _data = data;
    118113    }
     114
     115    FlowSliceAxis getAxis()
     116    {
     117        return _sv.slicePos.axis;
     118    }
     119
     120    TransferFunction *getTransferFunction()
     121    {
     122        return _sv.transferFunction;
     123    }
    119124#if 0
    120     void activateSlice()
    121     {
    122         /* Must set axis before offset or position goes to wrong axis. */
    123         NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
    124         NanoVis::licRenderer->setOffset(_sv.slicePos.value);
    125         NanoVis::licRenderer->active(true);
    126     }
    127 
    128     void deactivateSlice()
    129     {
    130         NanoVis::licRenderer->active(false);
     125    void setAxis(FlowSliceAxis axis)
     126    {
     127        _sv.slicePos.axis = axis;
     128        if (NanoVis::licRenderer != NULL) {
     129            NanoVis::licRenderer->setSliceAxis(_sv.slicePos.axis);
     130        }
     131        if (NanoVis::velocityArrowsSlice != NULL) {
     132            NanoVis::velocityArrowsSlice->setSliceAxis(_sv.slicePos.axis);
     133        }
     134    }
     135
     136    void setCurrentPosition(float position)
     137    {
     138        _sv.slicePos.value = position;
     139        if (NanoVis::licRenderer != NULL) {
     140            NanoVis::licRenderer->setSlicePosition(_sv.slicePos.value);
     141        }
     142        if (NanoVis::velocityArrowsSlice != NULL) {
     143            NanoVis::velocityArrowsSlice->setSlicePosition(_sv.slicePos.value);
     144        }
     145    }
     146
     147    void setLICActive(bool state)
     148    {
     149        _sv.sliceVisible = state;
     150        if (NanoVis::licRenderer != NULL) {
     151            NanoVis::licRenderer->setVectorField(_volume);
     152            NanoVis::licRenderer->setSliceAxis(_sv.slicePos.axis);
     153            NanoVis::licRenderer->setSlicePosition(_sv.slicePos.value);
     154            NanoVis::licRenderer->visible(state);
     155        }
     156    }
     157
     158    void setArrowsActive(bool state)
     159        _sv.showArrows = state;
     160        if (NanoVis::velocityArrowsSlice != NULL) {
     161            NanoVis::velocityArrowsSlice->setVectorField(_volume);
     162            NanoVis::velocityArrowsSlice->setSliceAxis(_sv.slicePos.axis);
     163            NanoVis::velocityArrowsSlice->setSlicePosition(_sv.slicePos.value);
     164            NanoVis::velocityArrowsSlice->visible(_sv.showArrows);
     165        }
    131166    }
    132167#endif
    133     SliceAxis getAxis()
    134     {
    135         return (SliceAxis)_sv.slicePos.axis;
    136     }
    137 
    138     TransferFunction *getTransferFunction()
    139     {
    140         return _sv.transferFunction;
    141     }
    142 
    143     float getRelativePosition();
    144 
    145     void setAxis()
    146     {
    147         NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
    148     }
    149 
    150     void setAxis(Flow::SliceAxis axis)
    151     {
    152         _sv.slicePos.axis = axis;
    153         NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
    154     }
    155 
    156     void setCurrentPosition(float position)
    157     {
    158         _sv.slicePos.value = position;
    159         NanoVis::licRenderer->setOffset(_sv.slicePos.value);
    160     }
    161 
    162     void setCurrentPosition()
    163     {
    164         NanoVis::licRenderer->setOffset(_sv.slicePos.value);
    165     }
    166 
    167     void setActive(bool state)
    168     {
    169         _sv.sliceVisible = state;
    170         NanoVis::licRenderer->active(state);
    171     }
    172 
    173     void setActive()
    174     {
    175         NanoVis::licRenderer->active(_sv.sliceVisible);
    176     }
    177 
    178168    const Volume *getVolume() const
    179169    {
     
    190180    }
    191181
     182    bool configure();
     183
    192184    Tcl_Command getCommandToken()
    193185    {
     
    195187    }
    196188
    197     static float getRelativePosition(FlowPosition *pos);
     189    float getRelativePosition(FlowPosition *pos);
     190
     191    static bool updatePending;
     192    static double magMin, magMax;
    198193
    199194private:
     
    203198    typedef std::tr1::unordered_map<BoxId, FlowBox *> BoxHashmap;
    204199
    205     void configure();
     200    float *getScaledVector();
     201
     202    Volume *makeVolume(float *data);
    206203
    207204    void renderBoxes();
  • trunk/packages/vizservers/nanovis/FlowBox.cpp

    r3611 r3630  
    4545
    4646void
    47 FlowBox::getWorldSpaceBounds(Vector3f& bboxMin,
    48                              Vector3f& bboxMax,
    49                              const Volume *vol) const
     47FlowBox::getBounds(Vector3f& bboxMin,
     48                   Vector3f& bboxMax) const
    5049{
    51     bboxMin.set(FLT_MAX, FLT_MAX, FLT_MAX);
    52     bboxMax.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    53 
    54     Vector3f origin = vol->location();
    55     Vector3f scale = vol->getPhysicalScaling();
    56 
    57     Matrix4x4d mat;
    58     mat.makeTranslation(origin);
    59     Matrix4x4d mat2;
    60     mat2.makeScale(scale);
    61 
    62     mat.multiply(mat2);
    63 
    64     Vector3f min, max;
    65     min.x = vol->xAxis.min();
    66     min.y = vol->yAxis.min();
    67     min.z = vol->zAxis.min();
    68     max.x = vol->xAxis.max();
    69     max.y = vol->yAxis.max();
    70     max.z = vol->zAxis.max();
    71 
    72     float x0, y0, z0, x1, y1, z1;
    73     x0 = y0 = z0 = 0.0f;
    74     x1 = y1 = z1 = 0.0f;
    75     if (max.x > min.x) {
    76         x0 = (_sv.corner1.x - min.x) / (max.x - min.x);
    77         x1 = (_sv.corner2.x - min.x) / (max.x - min.x);
    78     }
    79     if (max.y > min.y) {
    80         y0 = (_sv.corner1.y - min.y) / (max.y - min.y);
    81         y1 = (_sv.corner2.y - min.y) / (max.y - min.y);
    82     }
    83     if (max.z > min.z) {
    84         z0 = (_sv.corner1.z - min.z) / (max.z - min.z);
    85         z1 = (_sv.corner2.z - min.z) / (max.z - min.z);
    86     }
    87 
    88     TRACE("Box model bounds: (%g,%g,%g) - (%g,%g,%g)",
    89           x0, y0, z0, x1, y1, z1);
    90 
    91     Vector3f modelMin(x0, y0, z0);
    92     Vector3f modelMax(x1, y1, z1);
    93 
    94     Vector4f bvert[8];
    95     bvert[0] = Vector4f(modelMin.x, modelMin.y, modelMin.z, 1);
    96     bvert[1] = Vector4f(modelMax.x, modelMin.y, modelMin.z, 1);
    97     bvert[2] = Vector4f(modelMin.x, modelMax.y, modelMin.z, 1);
    98     bvert[3] = Vector4f(modelMin.x, modelMin.y, modelMax.z, 1);
    99     bvert[4] = Vector4f(modelMax.x, modelMax.y, modelMin.z, 1);
    100     bvert[5] = Vector4f(modelMax.x, modelMin.y, modelMax.z, 1);
    101     bvert[6] = Vector4f(modelMin.x, modelMax.y, modelMax.z, 1);
    102     bvert[7] = Vector4f(modelMax.x, modelMax.y, modelMax.z, 1);
    103 
    104     for (int i = 0; i < 8; i++) {
    105         Vector4f worldVert = mat.transform(bvert[i]);
    106         if (worldVert.x < bboxMin.x) bboxMin.x = worldVert.x;
    107         if (worldVert.x > bboxMax.x) bboxMax.x = worldVert.x;
    108         if (worldVert.y < bboxMin.y) bboxMin.y = worldVert.y;
    109         if (worldVert.y > bboxMax.y) bboxMax.y = worldVert.y;
    110         if (worldVert.z < bboxMin.z) bboxMin.z = worldVert.z;
    111         if (worldVert.z > bboxMax.z) bboxMax.z = worldVert.z;
    112     }
    113 
    114     TRACE("Box world bounds: (%g,%g,%g) - (%g,%g,%g)",
    115           bboxMin.x, bboxMin.y, bboxMin.z,
    116           bboxMax.x, bboxMax.y, bboxMax.z);
     50    bboxMin.set(_sv.corner1.x, _sv.corner1.y, _sv.corner1.z);
     51    bboxMax.set(_sv.corner2.x, _sv.corner2.y, _sv.corner2.z);
    11752}
    11853
     
    13166    glPushMatrix();
    13267
    133     Vector3f origin = vol->location();
    134     glTranslatef(origin.x, origin.y, origin.z);
    135 
    136     Vector3f scale = vol->getPhysicalScaling();
    137     glScalef(scale.x, scale.y, scale.z);
    138 
    139     Vector3f min, max;
    140     min.x = vol->xAxis.min();
    141     min.y = vol->yAxis.min();
    142     min.z = vol->zAxis.min();
    143     max.x = vol->xAxis.max();
    144     max.y = vol->yAxis.max();
    145     max.z = vol->zAxis.max();
    146 
    147     TRACE("box is %g,%g %g,%g %g,%g",
     68    TRACE("box bounds %g,%g %g,%g %g,%g",
    14869          _sv.corner1.x, _sv.corner2.x,
    14970          _sv.corner1.y, _sv.corner2.y,
    15071          _sv.corner1.z, _sv.corner2.z);
    151     TRACE("world is %g,%g %g,%g %g,%g",
    152           min.x, max.x, min.y, max.y, min.z, max.z);
    15372
    15473    float x0, y0, z0, x1, y1, z1;
    155     x0 = y0 = z0 = 0.0f;
    156     x1 = y1 = z1 = 0.0f;
    157     if (max.x > min.x) {
    158         x0 = (_sv.corner1.x - min.x) / (max.x - min.x);
    159         x1 = (_sv.corner2.x - min.x) / (max.x - min.x);
    160     }
    161     if (max.y > min.y) {
    162         y0 = (_sv.corner1.y - min.y) / (max.y - min.y);
    163         y1 = (_sv.corner2.y - min.y) / (max.y - min.y);
    164     }
    165     if (max.z > min.z) {
    166         z0 = (_sv.corner1.z - min.z) / (max.z - min.z);
    167         z1 = (_sv.corner2.z - min.z) / (max.z - min.z);
    168     }
    169     TRACE("box bounds: %g,%g %g,%g %g,%g",
    170           x0, x1, y0, y1, z0, z1);
     74
     75    x0 = _sv.corner1.x;
     76    x1 = _sv.corner2.x;
     77    y0 = _sv.corner1.y;
     78    y1 = _sv.corner2.y;
     79    z0 = _sv.corner1.z;
     80    z1 = _sv.corner2.z;
    17181
    17282    glColor4d(_sv.color.r, _sv.color.g, _sv.color.b, _sv.color.a);
  • trunk/packages/vizservers/nanovis/FlowBox.h

    r3613 r3630  
    6363    }
    6464
    65     void getWorldSpaceBounds(vrmath::Vector3f& min,
    66                              vrmath::Vector3f& max,
    67                              const Volume *volume) const;
     65    void getBounds(vrmath::Vector3f& min,
     66                   vrmath::Vector3f& max) const;
    6867
    6968private:
  • trunk/packages/vizservers/nanovis/FlowCmd.cpp

    r3611 r3630  
    104104
    105105Rappture::SwitchSpec FlowParticles::_switches[] = {
    106     {Rappture::SWITCH_CUSTOM, "-axis", "string",
     106    {Rappture::SWITCH_CUSTOM, "-axis", "axis",
    107107     offsetof(FlowParticlesValues, position.axis), 0, 0, &axisSwitch},
    108108    {Rappture::SWITCH_CUSTOM, "-color", "{r g b a}",
     
    197197    }
    198198    flow->data(dataPtr);
    199     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     199    Flow::updatePending = true;
     200    NanoVis::eventuallyRedraw();
    200201    return TCL_OK;
    201202}
     
    266267        dataPtr->convert(u2dPtr);
    267268        delete u2dPtr;
     269#if 0
     270    } else if ((length > 14) && (strncmp(bytes, "# vtk DataFile", 14) == 0)) {
     271        TRACE("VTK loading...");
     272        std::stringstream fdata;
     273        fdata.write(bytes, length);
     274        if (length <= 0) {
     275            ERROR("data buffer is empty");
     276            abort();
     277        }
     278        Rappture::Outcome context;
     279        volume = load_vtk_volume_stream(context, tag, fdata);
     280        if (volume == NULL) {
     281            Tcl_AppendResult(interp, context.remark(), (char*)NULL);
     282            return TCL_ERROR;
     283        }
     284#endif
    268285    } else {
    269286        TRACE("header is %.14s", buf.bytes());
     
    307324#endif
    308325    }
    309     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     326    Flow::updatePending = true;
     327    NanoVis::eventuallyRedraw();
    310328    return TCL_OK;
    311329}
     
    353371    const char *string = Tcl_GetString(objPtr);
    354372    if (string[1] == '\0') {
    355         Flow::SliceAxis *axisPtr = (Flow::SliceAxis *)(record + offset);
     373        FlowSliceAxis *axisPtr = (FlowSliceAxis *)(record + offset);
    356374        char c;
    357375        c = tolower((unsigned char)string[0]);
    358376        if (c == 'x') {
    359             *axisPtr = Flow::AXIS_X;
     377            *axisPtr = AXIS_X;
    360378            return TCL_OK;
    361379        } else if (c == 'y') {
    362             *axisPtr = Flow::AXIS_Y;
     380            *axisPtr = AXIS_Y;
    363381            return TCL_OK;
    364382        } else if (c == 'z') {
    365             *axisPtr = Flow::AXIS_Z;
     383            *axisPtr = AXIS_Z;
    366384            return TCL_OK;
    367385        }
     
    564582        return TCL_ERROR;
    565583    }
    566     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     584    if (flow->configure()) {
     585        Flow::updatePending = true;
     586    }
     587    NanoVis::eventuallyRedraw();
    567588    return TCL_OK;
    568589}
     
    587608    }
    588609    particles->configure();
     610    Flow::updatePending = true;
    589611    NanoVis::eventuallyRedraw();
    590612    Tcl_SetObjResult(interp, objv[3]);
     
    608630        return TCL_ERROR;
    609631    }
    610     particles->configure();
    611     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     632    if (particles->configure()) {
     633        Flow::updatePending = true;
     634    }
     635    NanoVis::eventuallyRedraw();
    612636    return TCL_OK;
    613637}
     
    815839        return TCL_ERROR;
    816840    }
    817     if (NanoVis::flags & NanoVis::MAP_FLOWS) {
     841    if (Flow::updatePending) {
    818842        NanoVis::mapFlows();
    819843    }
    820     NanoVis::renderLegend(tf, NanoVis::magMin, NanoVis::magMax, w, h, label);
     844    NanoVis::renderLegend(tf, Flow::magMin, Flow::magMax, w, h, label);
    821845    return TCL_OK;
    822846}
     
    905929        }
    906930    }
    907     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     931    Flow::updatePending = true;
     932    NanoVis::eventuallyRedraw();
    908933    return TCL_OK;
    909934}
     
    939964    }
    940965    NanoVis::resetFlows();
    941     if (NanoVis::flags & NanoVis::MAP_FLOWS) {
     966    if (Flow::updatePending) {
    942967        NanoVis::mapFlows();
    943968    }
    944     NanoVis::advectFlows();
    945969    for (int i = 0; i < nSteps; i++) {
    946         if (NanoVis::licRenderer->active()) {
    947             NanoVis::licRenderer->convolve();
    948         }
     970        NanoVis::licRenderer->convolve();
    949971        NanoVis::advectFlows();
    950972    }
     
    974996{
    975997    assert(NanoVis::licRenderer != NULL);
    976     if (NanoVis::flags & NanoVis::MAP_FLOWS) {
     998    if (Flow::updatePending) {
    977999        NanoVis::mapFlows();
    9781000    }
    979     NanoVis::eventuallyRedraw();
    9801001    NanoVis::licRenderer->convolve();
    9811002    NanoVis::advectFlows();
     1003    NanoVis::eventuallyRedraw();
    9821004    return TCL_OK;
    9831005}
     
    11011123            break;
    11021124        }
    1103         if (NanoVis::licRenderer->active()) {
    1104             NanoVis::licRenderer->convolve();
    1105         }
     1125
     1126        NanoVis::licRenderer->convolve();
    11061127        NanoVis::advectFlows();
    11071128
  • trunk/packages/vizservers/nanovis/FlowParticles.cpp

    r3627 r3630  
    2828    _sv.position.value = 0.0f;
    2929    _sv.position.flags = RELPOS;
    30     _sv.position.axis = 0; // X_AXIS
     30    _sv.position.axis = AXIS_Z;
    3131    _sv.color.r = _sv.color.g = _sv.color.b = _sv.color.a = 1.0f;
    3232    _sv.isHidden = false;
     
    4444}
    4545
     46float
     47FlowParticles::getRelativePosition(FlowPosition *position)
     48{
     49    if (position->flags == RELPOS) {
     50        return position->value;
     51    }
     52    switch (position->axis) {
     53    case AXIS_X: 
     54        return (position->value - _volume->xAxis.min()) /
     55            (_volume->xAxis.max() - _volume->xAxis.min());
     56    case AXIS_Y: 
     57        return (position->value - _volume->yAxis.min()) /
     58            (_volume->yAxis.max() - _volume->yAxis.min());
     59    case AXIS_Z: 
     60        return (position->value - _volume->zAxis.min()) /
     61            (_volume->zAxis.max() - _volume->zAxis.min());
     62    }
     63    return 0.0;
     64}
     65
    4666void
    4767FlowParticles::render()
     
    4969    TRACE("Particles '%s' axis: %d pos: %g rel pos: %g",
    5070          _name.c_str(), _sv.position.axis, _sv.position.value,
    51           Flow::getRelativePosition(&_sv.position));
     71          getRelativePosition(&_sv.position));
    5272
    53     _renderer->setPos(Flow::getRelativePosition(&_sv.position));
     73    _renderer->setPos(getRelativePosition(&_sv.position));
    5474    _renderer->setAxis(_sv.position.axis);
    5575    assert(_renderer->active());
     
    5777}
    5878
    59 void
     79bool
    6080FlowParticles::configure()
    6181{
    62     _renderer->setPos(Flow::getRelativePosition(&_sv.position));
     82    bool needReset = false;
     83
    6384    _renderer->setColor(Color4f(_sv.color.r,
    6485                                _sv.color.g,
     
    6687                                _sv.color.a));
    6788    _renderer->particleSize(_sv.particleSize);
    68     _renderer->setAxis(_sv.position.axis);
     89    if (_renderer->getAxis() != _sv.position.axis) {
     90        needReset = true;
     91        _renderer->setAxis(_sv.position.axis);
     92    }
     93    float pos = getRelativePosition(&_sv.position);
     94    if (_renderer->getPos() != pos) {
     95        needReset = true;
     96        _renderer->setPos(pos);
     97    }
    6998    _renderer->active(!_sv.isHidden);
     99
     100    return needReset;
    70101}
  • trunk/packages/vizservers/nanovis/FlowParticles.h

    r3613 r3630  
    7777    }
    7878
    79     void setVectorField(Volume *volume, const vrmath::Vector3f& location,
    80                         float scaleX, float scaleY, float scaleZ,
    81                         float max)
     79    void setVectorField(Volume *volume)
    8280    {
    83         _renderer->
    84             setVectorField(volume->textureID(),
    85                            location,
    86                            scaleX,
    87                            scaleY,
    88                            scaleZ,
    89                            max);
     81        _volume = volume;
     82        _renderer->setVectorField(volume);
    9083    }
    9184
    92     void configure();
     85    float getRelativePosition(FlowPosition *position);
     86
     87    bool configure();
    9388
    9489private:
     
    9994    std::string _name;
    10095    nv::ParticleRenderer *_renderer;        ///< Particle renderer
     96    Volume *_volume;
    10197    FlowParticlesValues _sv;
    10298
  • trunk/packages/vizservers/nanovis/FlowTypes.h

    r3613 r3630  
    1414namespace nv {
    1515
     16enum FlowSliceAxis {
     17    AXIS_X,
     18    AXIS_Y,
     19    AXIS_Z
     20};
     21
    1622struct FlowColor {
    1723    float r, g, b, a;
     
    2531    float value;
    2632    unsigned int flags;
    27     int axis;
     33    FlowSliceAxis axis;
    2834};
    2935
  • trunk/packages/vizservers/nanovis/Grid.cpp

    r3627 r3630  
    3838}
    3939
     40void Grid::getBounds(vrmath::Vector3f& bboxMin, vrmath::Vector3f& bboxMax) const
     41{
     42    bboxMin.set(xAxis.min(), yAxis.min(), zAxis.min());
     43    bboxMax.set(xAxis.min() + xAxis.range(),
     44                yAxis.min() + yAxis.range(),
     45                zAxis.min() + zAxis.range());
     46}
     47
    4048void Grid::render()
    4149{
     
    5563    glPushMatrix();
    5664
    57     double xDataRange = xAxis.dataMax() - xAxis.dataMin();
    58     double yDataRange = yAxis.dataMax() - yAxis.dataMin();
    59     double zDataRange = zAxis.dataMax() - zAxis.dataMin();
    60 
    61     double paspectX = 1.0f;
    62     double paspectY = yDataRange / xDataRange;
    63     double paspectZ = zDataRange / xDataRange;
    64  
    65     double xscale = xAxis.range() / xDataRange;
    66     double yscale = yAxis.range() / xDataRange;
    67     double zscale = zAxis.range() / xDataRange;
    68 
    69     double xoffset = (xAxis.min() - xAxis.dataMin()) * xAxis.scale();
    70     double yoffset = (yAxis.min() - yAxis.dataMin()) * yAxis.scale();
    71     double zoffset = (zAxis.min() - zAxis.dataMin()) * zAxis.scale();
    72 
    73     TRACE("Axis ranges: %g %g %g", xAxis.range(), yAxis.range(), zAxis.range());
    74     TRACE("Axis scales: %g %g %g", xAxis.scale(), yAxis.scale(), zAxis.scale());
    75     TRACE("Axis min/max: %g,%g %g,%g %g,%g",
    76           xAxis.min(), xAxis.max(),
    77           yAxis.min(), yAxis.max(),
    78           zAxis.min(), zAxis.max());
    79     TRACE("Axis vmin/vmax: %g,%g %g,%g %g,%g",
    80           xAxis.dataMin(), xAxis.dataMax(),
    81           yAxis.dataMin(), yAxis.dataMax(),
    82           zAxis.dataMin(), zAxis.dataMax());
    83     TRACE("paspect: %g %g %g", paspectX, paspectY, paspectZ);
    84     TRACE("scale: %g %g %g", xscale, yscale, zscale);
    85 
    86     glTranslatef(-0.5f * paspectX, -0.5f * paspectY, -0.5f * paspectZ);
    87     glScalef(xscale, yscale, zscale);
    88     glTranslatef(xoffset, yoffset, zoffset);
     65    glTranslatef(xAxis.min(), yAxis.min(), zAxis.min());
     66    glScalef(xAxis.range(), yAxis.range(), zAxis.range());
    8967
    9068    glLineWidth(2.0f);
  • trunk/packages/vizservers/nanovis/Grid.h

    r3627 r3630  
    77#define NV_GRID_H
    88
     9#include <vrmath/Vector3f.h>
    910#include <vrmath/Color4f.h>
    1011
     
    4950    void setFont(nv::util::Fonts *font);
    5051
     52    void getBounds(vrmath::Vector3f& bboxMin,
     53                   vrmath::Vector3f& bboxMax) const;
     54
    5155    Axis xAxis;
    5256    Axis yAxis;
  • trunk/packages/vizservers/nanovis/HeightMap.cpp

    r3612 r3630  
    4040{
    4141    _shader = new Shader();
    42     _shader->loadFragmentProgram("heightcolor.cg", "main");
     42    _shader->loadFragmentProgram("heightcolor.cg");
    4343}
    4444
     
    490490
    491491void
    492 HeightMap::getWorldSpaceBounds(Vector3f& bboxMin,
    493                                Vector3f& bboxMax) const
    494 {
    495     bboxMin.set(FLT_MAX, FLT_MAX, FLT_MAX);
    496     bboxMax.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    497 
    498    
    499 }
     492HeightMap::getBounds(Vector3f& bboxMin,
     493                     Vector3f& bboxMax) const
     494{
     495    bboxMin.set(xAxis.min(), yAxis.min(), zAxis.min());
     496    bboxMax.set(xAxis.max(), yAxis.max(), zAxis.max());
     497}
  • trunk/packages/vizservers/nanovis/HeightMap.h

    r3612 r3630  
    113113    }
    114114
    115     void getWorldSpaceBounds(vrmath::Vector3f& bboxMin, vrmath::Vector3f& bboxMax) const;
     115    void getBounds(vrmath::Vector3f& bboxMin, vrmath::Vector3f& bboxMax) const;
    116116
    117117    AxisRange xAxis, yAxis, zAxis, wAxis;
  • trunk/packages/vizservers/nanovis/LIC.cpp

    r3612 r3630  
    2424using namespace vrmath;
    2525
    26 LIC::LIC(int size, int width, int height, int axis,
     26LIC::LIC(FlowSliceAxis axis,
    2727         float offset) :
    28     _width(width),
    29     _height(height),
    30     _size(size),
     28    _width(NPIX),
     29    _height(NPIX),
     30    _size(NMESH),
    3131    _scale(1.0f, 1.0f, 1.0f),
    3232    _origin(0, 0, 0),
     
    4141    _disListID(0),
    4242    _vectorFieldId(0),
    43     _activate(false)
    44 {
    45     _sliceVector = new float[_size*_size*4];
     43    _visible(false)
     44{
     45    _sliceVector = new float[_size * _size * 4];
    4646    memset(_sliceVector, 0, sizeof(float) * _size * _size * 4);
    4747
     
    104104
    105105    _renderVelShader = new Shader();
    106     _renderVelShader->loadFragmentProgram("render_vel.cg", "main");
     106    _renderVelShader->loadFragmentProgram("render_vel.cg");
    107107
    108108    makePatterns();
     
    178178}
    179179
    180 void LIC::makeMagnitudes()
     180void
     181LIC::makeMagnitudes()
    181182{
    182183    GLubyte mag[NMESH][NMESH][4];
     
    246247
    247248    switch (_axis) {
    248     case 0:
     249    case AXIS_X:
    249250        _renderVelShader->setFPParameter3f("projection_vector", 0., 1., 1.);
    250251        break;
    251     case 1:
     252    case AXIS_Y:
    252253        _renderVelShader->setFPParameter3f("projection_vector", 1., 0., 1.);
    253254        break;
    254255    default:
    255     case 2:
     256    case AXIS_Z:
    256257        _renderVelShader->setFPParameter3f("projection_vector", 1., 1., 0.);
    257258        break;
     
    261262    {
    262263        switch (_axis) {
    263         case 0:
     264        case AXIS_X:
    264265            glTexCoord3f(_offset, 0., 0.); glVertex2f(0.,    0.);
    265266            glTexCoord3f(_offset, 1., 0.); glVertex2f(_size, 0.);
     
    267268            glTexCoord3f(_offset, 0., 1.); glVertex2f(0.,    _size);
    268269            break;
    269         case 1:
     270        case AXIS_Y:
    270271            glTexCoord3f(0., _offset, 0.); glVertex2f(0.,    0.);
    271272            glTexCoord3f(1., _offset, 0.); glVertex2f(_size, 0.);
     
    273274            glTexCoord3f(0., _offset, 1.); glVertex2f(0.,    _size);
    274275            break;
    275         case 2:
     276        case AXIS_Z:
    276277            glTexCoord3f(0., 0., _offset); glVertex2f(0.,    0.);
    277278            glTexCoord3f(1., 0., _offset); glVertex2f(_size, 0.);
     
    428429LIC::render()
    429430{
    430     if (_vectorFieldId == 0) {
     431    if (_vectorFieldId == 0 || !_visible) {
    431432        return;
    432433    }
     
    451452    glBegin(GL_QUADS);
    452453    switch (_axis) {
    453     case 0:
     454    case AXIS_X:
    454455        glNormal3f(1, 0, 0);
    455456        glTexCoord2f(0, 0); glVertex3f(_offset, 0, 0);
     
    458459        glTexCoord2f(0, 1); glVertex3f(_offset, 0, 1);
    459460        break;
    460     case 1:
     461    case AXIS_Y:
    461462        glNormal3f(0, 1, 0);
    462463        glTexCoord2f(0, 0); glVertex3f(0, _offset, 0);
     
    465466        glTexCoord2f(0, 1); glVertex3f(0, _offset, 1);
    466467        break;
    467     case 2:
     468    case AXIS_Z:
    468469        glNormal3f(0, 0, 1);
    469470        glTexCoord2f(0, 0); glVertex3f(0, 0, _offset);
     
    483484
    484485void
    485 LIC::setVectorField(unsigned int texID, const Vector3f& origin,
    486                       float scaleX, float scaleY, float scaleZ, float max)
    487 {
    488     TRACE("LIC: vector field is assigned [%d]", texID);
    489     _vectorFieldId = texID;
    490     _origin = origin;
    491     _scale = Vector3f(scaleX, scaleY, scaleZ);
    492     _max = max;
     486LIC::setVectorField(Volume *volume)
     487{
     488    TRACE("LIC: vector field is assigned [%d]", volume->textureID());
     489
     490    _vectorFieldId = volume->textureID();
     491    Vector3f bmin, bmax;
     492    volume->getBounds(bmin, bmax);
     493    _origin = bmin;
     494    _scale.set(bmax.x-bmin.x, bmax.y-bmin.y, bmax.z-bmin.z);
     495    _max = volume->wAxis.max();
    493496
    494497    makePatterns();
     
    507510    //TRACE("(xi yi) = (%d %d), ", xi, yi);
    508511   switch (_axis) {
    509    case 0:
     512   case AXIS_X:
    510513       vx = _sliceVector[4 * (xi+yi*_size)+2];
    511514       vy = _sliceVector[4 * (xi+yi*_size)+1];
    512515       break;
    513    case 1:
     516   case AXIS_Y:
    514517       vx = _sliceVector[4 * (xi+yi*_size)];
    515518       vy = _sliceVector[4 * (xi+yi*_size)+2];
    516519       break;
    517    case 2:
     520   case AXIS_Z:
    518521   default:
    519522       vx = _sliceVector[4 * (xi+yi*_size)];
     
    537540
    538541void
    539 LIC::setOffset(float offset)
     542LIC::setSlicePosition(float offset)
    540543{
    541544    _offset = offset;
     
    543546}
    544547
    545 void LIC::setAxis(int axis)
     548void LIC::setSliceAxis(FlowSliceAxis axis)
    546549{
    547550    _axis = axis;
  • trunk/packages/vizservers/nanovis/LIC.h

    r3612 r3630  
    1313#include <vrmath/Vector3f.h>
    1414
     15#include "FlowTypes.h"
    1516#include "Volume.h"
    1617#include "Shader.h"
     
    2122{
    2223public:
    23     LIC(int size, int width, int height, int axis, float offset);
     24    LIC(FlowSliceAxis axis = AXIS_Z, float offset = 0.f);
    2425    ~LIC();
    2526
     
    3031    void render();
    3132
    32     void makePatterns();
     33    void setSlicePosition(float pos);
    3334
    34     void makeMagnitudes();
    35 
    36     void getVelocity(float x, float y, float *px, float *py);
    37 
    38     void getSlice();
    39 
    40     void setOffset(float offset);
     35    float getSlicePosition() const
     36    {
     37        return _offset;
     38    }
    4139
    4240    /**
    4341     * @brief Specify the perpendicular axis
    44      *
    45      * 0 : x axis<br>
    46      * 1 : y axis<br>
    47      * 2 : z axis<br>
    4842     */
    49     void setAxis(int axis);
     43    void setSliceAxis(FlowSliceAxis axis);
    5044
    51     void setVectorField(unsigned int texID, const vrmath::Vector3f& origin,
    52                         float scaleX, float scaleY, float scaleZ, float max);
     45    FlowSliceAxis getSliceAxis() const
     46    {
     47        return _axis;
     48    }
     49
     50    void setVectorField(Volume *volume);
    5351
    5452    void reset();
     
    5654    void visible(bool state)
    5755    {
    58         _isHidden = !state;
     56        _visible = state;
    5957    }
    6058
    6159    bool visible() const
    6260    {
    63         return (!_isHidden);
    64     }
    65 
    66     void active(bool state)
    67     {
    68         _activate = state;
    69     }
    70 
    71     bool active() const
    72     {
    73         return _activate;
     61        return _visible;
    7462    }
    7563
    7664private:
     65    void getVelocity(float x, float y, float *px, float *py);
     66
     67    void getSlice();
     68
     69    void makePatterns();
     70
     71    void makeMagnitudes();
     72
    7773    /**
    7874     * @brief the normal vector of the LIC plane,
     
    8985                                   plane to fit the actual dimensions */
    9086    vrmath::Vector3f _origin;
    91     float _offset;            ///< [0,1] offset of slice plane
    92     int _axis;                ///< Axis normal to slice plane
     87    float _offset;              ///< [0,1] offset of slice plane
     88    FlowSliceAxis _axis;        ///< Axis normal to slice plane
    9389
    9490    //some convolve variables. They can pretty much stay fixed
     
    114110     * flag for rendering
    115111     */
    116     bool _activate;
    117     bool _isHidden;                     // Indicates if LIC plane is displayed.
     112    bool _visible;                      // Indicates if LIC plane is displayed.
    118113};
    119114
  • trunk/packages/vizservers/nanovis/Makefile.in

    r3627 r3630  
    287287ContourLineFilter.o: ContourLineFilter.cpp ContourLineFilter.h
    288288ConvexPolygon.o: ConvexPolygon.cpp ConvexPolygon.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h Plane.h
    289 Flow.o: Flow.cpp Flow.h FlowCmd.h FlowTypes.h FlowBox.h FlowParticles.h Switch.h Trace.h
     289Flow.o: Flow.cpp Flow.h FlowCmd.h FlowTypes.h FlowBox.h FlowParticles.h LIC.h VelocityArrowsSlice.h Switch.h Unirect.h Volume.h TransferFunction.h Trace.h
    290290FlowBox.o: FlowBox.cpp FlowBox.h FlowTypes.h Switch.h Trace.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h
    291291FlowCmd.o: FlowCmd.cpp FlowCmd.h FlowParticles.h FlowBox.h FlowTypes.h Command.h PPMWriter.h Switch.h Trace.h TransferFunction.h nanovis.h CmdProc.h LIC.h Unirect.h Volume.h VelocityArrowsSlice.h $(VRMATH_DIR)/include/vrmath/Vector3f.h
     
    313313RenderVertexArray.o: RenderVertexArray.cpp RenderVertexArray.h
    314314Shader.o: Shader.cpp Shader.h
     315ShaderGL.o: ShaderGL.cpp ShaderGL.h
    315316StdVertexShader.o: StdVertexShader.cpp StdVertexShader.h Shader.h
    316317Switch.o: Switch.cpp Switch.h
     
    321322TransferFunction.o: TransferFunction.cpp
    322323Unirect.o: Unirect.cpp Unirect.h Command.h Trace.h
    323 VelocityArrowsSlice.o: VelocityArrowsSlice.cpp VelocityArrowsSlice.h
     324VelocityArrowsSlice.o: VelocityArrowsSlice.cpp VelocityArrowsSlice.h nanovis.h Camera.h Volume.h Shader.h
    324325Volume.o: Volume.cpp Volume.h config.h define.h
    325326VolumeInterpolator.o: VolumeInterpolator.cpp VolumeInterpolator.h Volume.h
  • trunk/packages/vizservers/nanovis/OrientationIndicator.cpp

    r3605 r3630  
    1010#include <GL/glu.h>
    1111
     12#include <vrmath/Vector3f.h>
     13
    1214#include "OrientationIndicator.h"
    1315
     16using namespace vrmath;
    1417using namespace nv;
    1518
     
    1821    _visible(true),
    1922    _lineWidth(1.f),
    20     _quadric(gluNewQuadric())
     23    _quadric(gluNewQuadric()),
     24    _position(0,0,0),
     25    _scale(1,1,1)
    2126{
    2227}
     
    3742        return;
    3843
     44    glMatrixMode(GL_MODELVIEW);
     45    glPushMatrix();
     46    glTranslatef(_position.x, _position.y, _position.z);
     47    float scale = _scale.x;
     48    if (scale == 0 || _scale.y < scale) scale = _scale.y;
     49    if (scale == 0 || _scale.z < scale) scale = _scale.z;
     50    glScalef(scale, scale, scale);
     51
    3952    glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT);
    4053
     
    4861        glLineWidth(_lineWidth);
    4962        glDisable(GL_LIGHTING);
    50         glColor3f(1, 0, 0);
    51         glBegin(GL_LINES);
    52         glVertex3f(0, 0, 0);
    53         glVertex3f(0.5f, 0, 0);
    54         glEnd();
    55         glColor3f(0, 1, 0);
    56         glBegin(GL_LINES);
    57         glVertex3f(0, 0, 0);
    58         glVertex3f(0, 0.5f, 0);
    59         glEnd();
    60         glColor3f(0, 0, 1);
    61         glBegin(GL_LINES);
    62         glVertex3f(0, 0, 0);
    63         glVertex3f(0, 0, 0.5f);
    64         glEnd();
     63        if (_scale.x > 0) {
     64            glColor3f(1, 0, 0);
     65            glBegin(GL_LINES);
     66            glVertex3f(0, 0, 0);
     67            glVertex3f(0.5f, 0, 0);
     68            glEnd();
     69        }
     70        if (_scale.y > 0) {
     71            glColor3f(0, 1, 0);
     72            glBegin(GL_LINES);
     73            glVertex3f(0, 0, 0);
     74            glVertex3f(0, 0.5f, 0);
     75            glEnd();
     76        }
     77        if (_scale.z > 0) {
     78            glColor3f(0, 0, 1);
     79            glBegin(GL_LINES);
     80            glVertex3f(0, 0, 0);
     81            glVertex3f(0, 0, 0.5f);
     82            glEnd();
     83        }
    6584    }
    6685        break;
     
    7291        glEnable(GL_LIGHTING);
    7392        glEnable(GL_LIGHT0);
     93        glEnable(GL_NORMALIZE);
    7494
    7595        // X
    76         glColor3f(1, 0, 0);
    77         glPushMatrix();
    78         glRotatef(90, 0, 1, 0);
    79         gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
    80         glPopMatrix();
     96        if (_scale.x > 0) {
     97            glColor3f(1, 0, 0);
     98            glPushMatrix();
     99            glRotatef(90, 0, 1, 0);
     100            gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
     101            glPopMatrix();
    81102
    82         glPushMatrix();
    83         glTranslatef(0.3, 0., 0.);
    84         glRotatef(90, 0, 1, 0);
    85         gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
    86         glPopMatrix();
     103            glPushMatrix();
     104            glTranslatef(0.3, 0., 0.);
     105            glRotatef(90, 0, 1, 0);
     106            gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
     107            glPopMatrix();
     108        }
    87109
    88110        // Y
    89         glColor3f(0, 1, 0);
    90         glPushMatrix();
    91         glRotatef(-90, 1, 0, 0);
    92         gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
    93         glPopMatrix();
     111        if (_scale.y > 0) {
     112            glColor3f(0, 1, 0);
     113            glPushMatrix();
     114            glRotatef(-90, 1, 0, 0);
     115            gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
     116            glPopMatrix();
    94117
    95         glPushMatrix();
    96         glTranslatef(0., 0.3, 0.);
    97         glRotatef(-90, 1, 0, 0);
    98         gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
    99         glPopMatrix();
     118            glPushMatrix();
     119            glTranslatef(0., 0.3, 0.);
     120            glRotatef(-90, 1, 0, 0);
     121            gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
     122            glPopMatrix();
     123        }
    100124
    101125        // Z
    102         glColor3f(0, 0, 1);
    103         glPushMatrix();
    104         gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
    105         glPopMatrix();
     126        if (_scale.z > 0) {
     127            glColor3f(0, 0, 1);
     128            glPushMatrix();
     129            gluCylinder(qobj, 0.01, 0.01, 0.3, segments, 1);
     130            glPopMatrix();
    106131
    107         glPushMatrix();
    108         glTranslatef(0., 0., 0.3);
    109         gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
    110         glPopMatrix();
     132            glPushMatrix();
     133            glTranslatef(0., 0., 0.3);
     134            gluCylinder(qobj, 0.02, 0.0, 0.06, segments, 1);
     135            glPopMatrix();
     136        }
    111137    }
    112138        break;
     
    116142   
    117143    glPopAttrib();
     144    glPopMatrix();
    118145}
  • trunk/packages/vizservers/nanovis/OrientationIndicator.h

    r3613 r3630  
    77#ifndef NV_ORIENTATION_INDICATOR_H
    88#define NV_ORIENTATION_INDICATOR_H
     9
     10#include <vrmath/Vector3f.h>
    911
    1012namespace nv {
     
    3537    }
    3638
     39    void setPosition(const vrmath::Vector3f& pos)
     40    {
     41        _position = pos;
     42    }
     43
     44    void setScale(const vrmath::Vector3f& scale)
     45    {
     46        _scale = scale;
     47    }
     48
    3749private:
    3850    Representation _rep;
     
    4052    float _lineWidth;
    4153    void *_quadric;
     54
     55    vrmath::Vector3f _position;
     56    vrmath::Vector3f _scale;
    4257};
    4358
  • trunk/packages/vizservers/nanovis/ParticleAdvectionShader.cpp

    r3612 r3630  
    1212    _scale(1.0f, 1.0f, 1.0f),
    1313    _max(1.0f),
    14     _timeStep(0.0005f),
    15     _mode(1)
     14    _timeStep(0.0005f)
    1615{
    1716    init();
     
    2423void ParticleAdvectionShader::init()
    2524{
    26     loadFragmentProgram("update_pos.cg", "main");
     25    loadFragmentProgram("update_pos.cg");
    2726}
    2827
    2928void
    30 ParticleAdvectionShader::bind(unsigned int texID, unsigned int initPosTexID)
     29ParticleAdvectionShader::bind(unsigned int texID, unsigned int initPosTexID, bool init)
    3130{
    3231    setFPTextureParameter("pos_tex", texID);
     
    3534
    3635    setFPParameter1f("timestep", _timeStep);
    37     setFPParameter1f("max", _max);
    38     setFPParameter1f("mode", _mode);
     36    setFPParameter1f("max", init ? 0 : _max);
    3937    setFPParameter3f("scale", _scale.x, _scale.y, _scale.z);
    4038
  • trunk/packages/vizservers/nanovis/ParticleAdvectionShader.h

    r3613 r3630  
    2020    virtual ~ParticleAdvectionShader();
    2121
    22     virtual void bind(unsigned int texID, unsigned int initPosTexID);
     22    virtual void bind(unsigned int texID, unsigned int initPosTexID, bool init);
    2323
    2424    virtual void unbind();
  • trunk/packages/vizservers/nanovis/ParticleRenderer.cpp

    r3627 r3630  
    1313#include <GL/glew.h>
    1414
     15#include <vrmath/Vector3f.h>
    1516#include <vrmath/Color4f.h>
    1617
    1718#include "ParticleRenderer.h"
     19#include "Volume.h"
    1820#include "define.h"
    1921#include "Trace.h"
    2022
     23using namespace vrmath;
    2124using namespace nv;
    22 
    23 ParticleAdvectionShader *ParticleRenderer::_advectionShader = NULL;
    24 ParticleAdvectionShaderInstance shaderInstance;
    2525
    2626ParticleRenderer::ParticleRenderer(int w, int h) :
     
    3737    _activate(false),
    3838    _slicePos(0.0),
    39     _sliceAxis(0),
     39    _sliceAxis(AXIS_Z),
    4040    _color(0.2, 0.2, 1.0, 1.0),
    4141    _psysWidth(w),
     
    4343{
    4444    _data = new Particle[w * h];
    45     memset(_data, 0, sizeof(Particle) * w * h);
    4645
    4746    _vertexArray = new RenderVertexArray(_psysWidth * _psysHeight, 3, GL_FLOAT);
     
    104103#endif
    105104
    106     if (_advectionShader == NULL) {
    107         _advectionShader = new ParticleAdvectionShader();
    108     }
     105    _advectionShader = new ParticleAdvectionShader();
    109106}
    110107
     
    121118    glDeleteFramebuffersEXT(2, _psysFbo);
    122119
     120    delete _advectionShader;
    123121    delete _vertexArray;
    124122    delete [] _data;
     
    128126ParticleRenderer::initializeDataArray()
    129127{
    130     size_t n = _psysWidth * _psysHeight * 4;
    131     memset(_data, 0, sizeof(float)* n);
    132 
    133     int index;
    134     bool particle;
    135     float *p = (float *)_data;
     128    TRACE("Enter axis: %d pos: %g", _sliceAxis, _slicePos);
     129
     130    memset(_data, 0, sizeof(Particle) * _psysWidth * _psysHeight);
     131 
     132    bool hasParticle;
    136133    for (int i = 0; i < _psysWidth; i++) {
    137134        for (int j = 0; j < _psysHeight; j++) {
    138             index = i + _psysHeight*j;
    139             particle = (rand() % 256) > 150;
    140             if (particle) {
     135            Particle *p = &_data[i + _psysHeight*j];
     136            hasParticle = (rand() % 256) > 150;
     137             if (hasParticle) {
    141138                //assign any location (x,y,z) in range [0,1]
    142139                switch (_sliceAxis) {
    143                 case 0:
    144                     p[4*index]  = _slicePos;
    145                     p[4*index+1] = j/float(_psysHeight);
    146                     p[4*index+2] = i/float(_psysWidth);
     140                case AXIS_X:
     141                    p->x = _slicePos;
     142                    p->y = j/float(_psysHeight);
     143                    p->z = i/float(_psysWidth);
    147144                    break;
    148                 case 1:
    149                     p[4*index]  = j/float(_psysHeight);
    150                     p[4*index+1] = _slicePos;
    151                     p[4*index+2] = i/float(_psysWidth);
     145                case AXIS_Y:
     146                    p->x = j/float(_psysHeight);
     147                    p->y = _slicePos;
     148                    p->z = i/float(_psysWidth);
    152149                    break;
    153                 case 2:
    154                     p[4*index]  = j/float(_psysHeight);
    155                     p[4*index+1] = i/float(_psysWidth);
    156                     p[4*index+2] = _slicePos;
     150                case AXIS_Z:
     151                    p->x = j/float(_psysHeight);
     152                    p->y = i/float(_psysWidth);
     153                    p->z = _slicePos;
    157154                    break;
    158155                default:
    159                     p[4*index]   = 0;
    160                     p[4*index+1] = 0;
    161                     p[4*index+2] = 0;
    162                     p[4*index+3] = 0;
     156                    ERROR("Unknown axis");
    163157                }
    164 
    165158                //shorter life span, quicker iterations
    166                 p[4*index+3] = rand() / ((float) RAND_MAX) * 0.5  + 0.5f;
    167             } else {
    168                 p[4*index]   = 0;
    169                 p[4*index+1] = 0;
    170                 p[4*index+2] = 0;
    171                 p[4*index+3] = 0;
     159                p->life = rand() / ((float) RAND_MAX) * 0.5  + 0.5f;
    172160            }
    173161        }
     
    178166ParticleRenderer::initialize()
    179167{
     168    TRACE("Enter");
     169
    180170    initializeDataArray();
    181171
     
    192182    _flip = true;
    193183    _reborn = false;
     184    _psysFrame = 0;
    194185
    195186    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _initPosTex);
     
    226217ParticleRenderer::advect()
    227218{
     219    TRACE("Enter");
     220
    228221    if (_reborn)
    229222        reset();
     
    256249    glPushMatrix();
    257250    glLoadIdentity();
    258     //gluOrtho2D(0, _psysWidth, 0, _psysHeight);
    259251    glOrtho(0, _psysWidth, 0, _psysHeight, -10.0f, 10.0f);
    260252    glMatrixMode(GL_MODELVIEW);
     
    262254    glLoadIdentity();
    263255
    264     _advectionShader->bind(_psysTex[tex], _initPosTex);
     256    _advectionShader->bind(_psysTex[tex], _initPosTex, _psysFrame == 0);
    265257
    266258    draw_quad(_psysWidth, _psysHeight, _psysWidth, _psysHeight);
     
    282274    _psysFrame++;
    283275    if (_psysFrame == _maxLife) {
    284         _psysFrame = 0;
    285         // _reborn = true;
     276        //_psysFrame = 0;
     277        //_reborn = true;
    286278    }
    287279    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboOrig);
     
    294286{
    295287    _vertexArray->read(_psysWidth, _psysHeight);
    296 
    297     //_vertexArray->loadData(vert);     //does not work??
    298     //assert(glGetError()==0);
    299288}
    300289
     
    302291ParticleRenderer::render()
    303292{
     293    if (_psysFrame == 0) {
     294        TRACE("Initializing vertex array");
     295        advect();
     296    }
     297
    304298    glPushAttrib(GL_ENABLE_BIT);
    305299    glDisable(GL_TEXTURE_2D);
     
    328322
    329323void
    330 ParticleRenderer::setVectorField(unsigned int texID, const vrmath::Vector3f& origin,
    331                                  float scaleX, float scaleY, float scaleZ,
    332                                  float max)
    333 {
    334     _origin = origin;
    335     _scale.set(scaleX, scaleY, scaleZ);
     324ParticleRenderer::setVectorField(Volume *volume)
     325{
     326    Vector3f bmin, bmax;
     327    volume->getBounds(bmin, bmax);
     328    _origin = bmin;
     329    Vector3f scale(bmax.x-bmin.x, bmax.y-bmin.y, bmax.z-bmin.z);
     330    _scale.set(scale.x, scale.y, scale.z);
    336331    _advectionShader->setScale(_scale);
    337     _advectionShader->setVelocityVolume(texID, max);
    338 }
    339 
    340 void
    341 ParticleRenderer::setAxis(int axis)
    342 {
    343     _sliceAxis = axis;
    344     initializeDataArray();
     332    _advectionShader->setVelocityVolume(volume->textureID(),
     333                                        volume->wAxis.max());
     334}
     335
     336void
     337ParticleRenderer::setAxis(FlowSliceAxis axis)
     338{
     339    if (axis != _sliceAxis) {
     340        _sliceAxis = axis;
     341        initialize();
     342    }
    345343}
    346344
     
    348346ParticleRenderer::setPos(float pos)
    349347{
    350     _slicePos = pos;
    351     initializeDataArray();
    352 }
     348    if (pos != _slicePos) {
     349        _slicePos = pos;
     350        initialize();
     351    }
     352}
  • trunk/packages/vizservers/nanovis/ParticleRenderer.h

    r3627 r3630  
    1414#include <vrmath/Color4f.h>
    1515
     16#include "FlowTypes.h"
     17#include "Volume.h"
    1618#include "ParticleAdvectionShader.h"
    1719#include "RenderVertexArray.h"
     
    2325    float y;
    2426    float z;
    25     float aux;
     27    float life;
    2628
    2729    Particle()
     
    2931
    3032    Particle(float _x, float _y, float _z, float _life) :
    31         x(_x), y(_y), z(_z), aux(_life)
     33        x(_x),
     34        y(_y),
     35        z(_z),
     36        life(_life)
    3237    {}
    3338};
     
    4045    ~ParticleRenderer();
    4146
    42     void setVectorField(unsigned int texID, const vrmath::Vector3f& origin,
    43                         float scaleX, float scaleY, float scaleZ, float max);
     47    void setVectorField(Volume *volume);
    4448
    4549    void initialize();
    4650
    4751    void advect();
    48 
    49     void updateVertexBuffer();
    5052
    5153    void reset();
     
    6870    }
    6971
    70     void setAxis(int axis);
     72    void setAxis(FlowSliceAxis axis);
     73
     74    FlowSliceAxis getAxis() const
     75    {
     76        return _sliceAxis;
     77    }
    7178
    7279    void setPos(float pos);
    7380
    74     void initializeDataArray();
     81    float getPos() const
     82    {
     83        return _slicePos;
     84    }
    7585
    7686    void particleSize(float size)
     
    8494    }
    8595
    86    static ParticleAdvectionShader *_advectionShader;
     96private:
     97    void initializeDataArray();
    8798
    88 private:
     99    void updateVertexBuffer();
     100
     101    ParticleAdvectionShader *_advectionShader;
     102
    89103    /// frame buffer objects: two are defined, flip them as input output every step
    90104    GLuint _psysFbo[2];
     
    96110
    97111    /// Count the frame number of particle system iteration
    98     int _psysFrame;
     112    unsigned int _psysFrame;
    99113
    100114    /// Reinitiate particles
     
    120134
    121135    float _slicePos;
    122     int _sliceAxis;
     136    FlowSliceAxis _sliceAxis;
    123137
    124138    vrmath::Color4f _color;
     
    129143};
    130144
    131 class ParticleAdvectionShaderInstance
    132 {
    133 public :
    134     ParticleAdvectionShaderInstance()
    135     {}
    136 
    137     ~ParticleAdvectionShaderInstance()
    138     {
    139         if (ParticleRenderer::_advectionShader) {
    140             delete ParticleRenderer::_advectionShader;
    141         }
    142     }
    143 };
    144 
    145145}
    146146
  • trunk/packages/vizservers/nanovis/PointShader.cpp

    r3612 r3630  
    1313    _normal(NULL)
    1414{
    15     loadVertexProgram("pointsvp.cg", "main");
     15    loadVertexProgram("pointsvp.cg");
    1616}
    1717
     
    2222void PointShader::bind()
    2323{
    24     setGLStateMatrixVPParameter("modelview", MODELVIEW_MATRIX, MATRIX_IDENTITY);
    25     setGLStateMatrixVPParameter("projection", PROJECTION_MATRIX, MATRIX_IDENTITY);
     24    setGLStateMatrixVPParameter("modelView", MODELVIEW_MATRIX, MATRIX_IDENTITY);
     25    setGLStateMatrixVPParameter("modelViewProj", MODELVIEW_PROJECTION_MATRIX, MATRIX_IDENTITY);
    2626
    2727    setVPParameter1f("atten", 1.0f);
  • trunk/packages/vizservers/nanovis/RegularVolumeShader.cpp

    r3612 r3630  
    1919void RegularVolumeShader::init()
    2020{
    21     loadFragmentProgram("one_volume.cg", "main");
     21    loadFragmentProgram("one_volume.cg");
    2222}
    2323
    2424void RegularVolumeShader::bind(unsigned int tfID, Volume *volume,
    25                                  int sliceMode, float sampleRatio)
     25                               int sliceMode, float sampleRatio)
    2626{
    2727    //regular cubic volume
    28     setGLStateMatrixFPParameter("modelViewInv", MODELVIEW_MATRIX,
    29                                 MATRIX_INVERSE);
    30     setGLStateMatrixFPParameter("modelView", MODELVIEW_MATRIX,
    31                                 MATRIX_IDENTITY);
    32 
    3328    setFPTextureParameter("volume", volume->textureID());
    3429    setFPTextureParameter("tf", tfID);
  • trunk/packages/vizservers/nanovis/RenderVertexArray.h

    r3613 r3630  
    2323    void loadData(void *data);  // load vertex data from memory
    2424
    25     void read(/*GLenum buffer,*/ int w, int h);   // read vertex data from
    26                                                   // frame buffer
     25    void read(int w, int h);   // read vertex data from frame buffer
     26
    2727    void setPointer(GLuint index);
    2828
  • trunk/packages/vizservers/nanovis/Shader.cpp

    r3612 r3630  
    2222CGcontext Shader::_cgContext = NULL;
    2323
    24 void Shader::initCg(CGprofile defaultVertexProfile,
    25                     CGprofile defaultFragmentProfile)
     24void Shader::init()
    2625{
    27     _defaultVertexProfile = defaultVertexProfile;
    28     _defaultFragmentProfile = defaultFragmentProfile;
    2926    _cgContext = cgCreateContext();
    3027}
    3128
    32 void Shader::exitCg()
     29void Shader::exit()
    3330{
    3431    setErrorCallback(NULL);
     
    9491}
    9592
    96 void Shader::loadVertexProgram(const char *fileName, const char *entryPoint)
     93void Shader::loadVertexProgram(const char *fileName)
    9794{
    9895    if (_cgVP != NULL) {
     
    10097    }
    10198    _cgVP = loadCgSourceProgram(_cgContext, fileName,
    102                                 _vertexProfile, entryPoint);
     99                                _vertexProfile, "main");
    103100    _vpFile = fileName;
    104101}
    105102
    106 void Shader::loadFragmentProgram(const char *fileName, const char *entryPoint)
     103void Shader::loadFragmentProgram(const char *fileName)
    107104{
    108105    if (_cgFP != NULL) {
     
    110107    }
    111108    _cgFP = loadCgSourceProgram(_cgContext, fileName,
    112                                 _fragmentProfile, entryPoint);
     109                                _fragmentProfile, "main");
    113110    _fpFile = fileName;
    114111}
     
    127124}
    128125
    129 void Shader::setErrorCallback(CgCallbackFunction callback)
     126void Shader::setErrorCallback(ShaderCallbackFunction callback)
    130127{
    131128    TRACE("Shader setting error callback to: %p", callback);
  • trunk/packages/vizservers/nanovis/Shader.h

    r3612 r3630  
    3131    };
    3232
    33     typedef void CgCallbackFunction(void);
     33    typedef void (*ShaderCallbackFunction)(void);
    3434
    3535    Shader();
     
    3838
    3939    /**
    40      * @brief create a Cg vertex program and load it
    41      * @param fileName the name of Cg program file
    42      * @param entryPoint a entry point of the Cg program
     40     * \brief Load and compile a vertex shader
     41     * \param fileName the name of the shader source file
    4342     */
    44     void loadVertexProgram(const char *fileName, const char *entryPoint);
     43    void loadVertexProgram(const char *fileName);
    4544
    4645    /**
    47      * @brief create a Cg fragment program and load it
    48      * @param fileName the name of Cg program file
    49      * @param entryPoint a entry point of the Cg program
     46     * \brief Load and compile a fragment shader
     47     * \param fileName the name of the shader source file
    5048     */
    51     void loadFragmentProgram(const char *fileName, const char *entryPoint);
    52 
    53     CGparameter getNamedParameterFromFP(const char *paramName)
    54     {
    55         if (_cgFP) {
    56             return cgGetNamedParameter(_cgFP, paramName);
    57         }
    58         ERROR("Unknown fragment program parameter: %s", paramName);
    59         return 0;
    60     }
    61 
    62     CGparameter getNamedParameterFromVP(const char *paramName)
    63     {
    64         if (_cgVP) {
    65             return cgGetNamedParameter(_cgVP, paramName);
    66         }
    67         ERROR("Unknown vertex program parameter: %s", paramName);
    68         return 0;
    69     }
     49    void loadFragmentProgram(const char *fileName);
    7050
    7151    void setVPParameter1f(const char *name, float val)
    7252    {
    73         CGparameter param = getVPParam(name);
     53        Parameter param = getVPParam(name);
    7454        if (param == NULL)
    7555            return;
     
    7959    void setFPParameter1f(const char *name, float val)
    8060    {
    81         CGparameter param = getFPParam(name);
     61        Parameter param = getFPParam(name);
    8262        if (param == NULL)
    8363            return;
     
    8767    void setVPParameter2f(const char *name, float val1, float val2)
    8868    {
    89         CGparameter param = getVPParam(name);
     69        Parameter param = getVPParam(name);
    9070        if (param == NULL)
    9171            return;
     
    9575    void setFPParameter2f(const char *name, float val1, float val2)
    9676    {
    97         CGparameter param = getFPParam(name);
     77        Parameter param = getFPParam(name);
    9878        if (param == NULL)
    9979            return;
     
    10383    void setVPParameter3f(const char *name, float val1, float val2, float val3)
    10484    {
    105         CGparameter param = getVPParam(name);
     85        Parameter param = getVPParam(name);
    10686        if (param == NULL)
    10787            return;
     
    11191    void setFPParameter3f(const char *name, float val1, float val2, float val3)
    11292    {
    113         CGparameter param = getFPParam(name);
     93        Parameter param = getFPParam(name);
    11494        if (param == NULL)
    11595            return;
     
    11999    void setVPParameter4f(const char *name, float val1, float val2, float val3, float val4)
    120100    {
    121         CGparameter param = getVPParam(name);
     101        Parameter param = getVPParam(name);
    122102        if (param == NULL)
    123103            return;
     
    127107    void setFPParameter4f(const char *name, float val1, float val2, float val3, float val4)
    128108    {
    129         CGparameter param = getFPParam(name);
     109        Parameter param = getFPParam(name);
    130110        if (param == NULL)
    131111            return;
     
    135115    void setVPMatrixParameterf(const char *name, float *mat)
    136116    {
    137         CGparameter param = getVPParam(name);
     117        Parameter param = getVPParam(name);
    138118        if (param == NULL)
    139119            return;
     
    143123    void setFPMatrixParameterf(const char *name, float *mat)
    144124    {
    145         CGparameter param = getFPParam(name);
     125        Parameter param = getFPParam(name);
    146126        if (param == NULL)
    147127            return;
     
    151131    void setVPTextureParameter(const char *name, GLuint texobj, bool enable = true)
    152132    {
    153         CGparameter param = getVPParam(name);
     133        Parameter param = getVPParam(name);
    154134        if (param == NULL)
    155135            return;
     
    161141    void setFPTextureParameter(const char *name, GLuint texobj, bool enable = true)
    162142    {
    163         CGparameter param = getFPParam(name);
     143        Parameter param = getFPParam(name);
    164144        if (param == NULL)
    165145            return;
     
    171151    void enableVPTextureParameter(const char *name)
    172152    {
    173         CGparameter param = getVPParam(name);
     153        Parameter param = getVPParam(name);
    174154        if (param == NULL)
    175155            return;
     
    179159    void enaableFPTextureParameter(const char *name)
    180160    {
    181         CGparameter param = getFPParam(name);
     161        Parameter param = getFPParam(name);
    182162        if (param == NULL)
    183163            return;
     
    187167    void disableVPTextureParameter(const char *name)
    188168    {
    189         CGparameter param = getVPParam(name);
     169        Parameter param = getVPParam(name);
    190170        if (param == NULL)
    191171            return;
     
    195175    void disableFPTextureParameter(const char *name)
    196176    {
    197         CGparameter param = getFPParam(name);
     177        Parameter param = getFPParam(name);
    198178        if (param == NULL)
    199179            return;
     
    204184                                     GLMatrixType type = MATRIX_IDENTITY)
    205185    {
    206         CGparameter param = getVPParam(name);
     186        Parameter param = getVPParam(name);
    207187        if (param == NULL)
    208188            return;
     
    213193                                     GLMatrixType type = MATRIX_IDENTITY)
    214194    {
    215         CGparameter param = getFPParam(name);
     195        Parameter param = getFPParam(name);
    216196        if (param == NULL)
    217197            return;
     
    239219    }
    240220
    241     void enableVertexProfile()
    242     {
    243         cgGLEnableProfile(_vertexProfile);
    244     }
    245 
    246     void disableVertexProfile()
    247     {
    248         cgGLDisableProfile(_vertexProfile);
    249     }
    250 
    251     void enableFragmentProfile()
    252     {
    253         cgGLEnableProfile(_fragmentProfile);
    254     }
    255 
    256     void disableFragmentProfile()
    257     {
    258         cgGLDisableProfile(_fragmentProfile);
    259     }
    260 
    261     static void initCg(CGprofile defaultVertexProfile = CG_PROFILE_VP40,
    262                        CGprofile defaultFragmentProfile = CG_PROFILE_FP40);
    263 
    264     static void exitCg();
     221    static void init();
     222
     223    static void exit();
    265224
    266225    static bool printErrorInfo();
    267226
    268     static void setErrorCallback(CgCallbackFunction callback);
    269 
    270     static CGcontext getCgContext()
    271     {
    272         return _cgContext;
    273     }
    274 
    275 protected:
    276     typedef std::tr1::unordered_map<std::string, CGparameter> ParameterHashmap;
    277 
    278     CGprogram getVP()
    279     {
    280         return _cgVP;
    281     }
    282 
    283     CGprogram getFP()
    284     {
    285         return _cgFP;
    286     }
    287 
    288     CGparameter getVPParam(const char *name)
    289     {
    290         CGparameter param;
     227    static void setErrorCallback(ShaderCallbackFunction callback);
     228
     229private:
     230    typedef CGparameter Parameter;
     231    typedef std::tr1::unordered_map<std::string, Parameter> ParameterHashmap;
     232
     233    Parameter getNamedParameterFromFP(const char *paramName)
     234    {
     235        if (_cgFP) {
     236            return cgGetNamedParameter(_cgFP, paramName);
     237        }
     238        ERROR("Unknown fragment program parameter: %s", paramName);
     239        return 0;
     240    }
     241
     242    Parameter getNamedParameterFromVP(const char *paramName)
     243    {
     244        if (_cgVP) {
     245            return cgGetNamedParameter(_cgVP, paramName);
     246        }
     247        ERROR("Unknown vertex program parameter: %s", paramName);
     248        return 0;
     249    }
     250
     251    Parameter getVPParam(const char *name)
     252    {
     253        Parameter param;
    291254        ParameterHashmap::iterator itr = _vpParams.find(name);
    292255        if (itr == _vpParams.end()) {
     
    302265    }
    303266
    304     CGparameter getFPParam(const char *name)
    305     {
    306         CGparameter param;
     267    Parameter getFPParam(const char *name)
     268    {
     269        Parameter param;
    307270        ParameterHashmap::iterator itr = _fpParams.find(name);
    308271        if (itr == _fpParams.end()) {
     
    318281    }
    319282
     283
    320284    void resetPrograms();
     285
     286
     287    CGprogram getVP()
     288    {
     289        return _cgVP;
     290    }
     291
     292    CGprogram getFP()
     293    {
     294        return _cgFP;
     295    }
     296
     297    void enableVertexProfile()
     298    {
     299        cgGLEnableProfile(_vertexProfile);
     300    }
     301
     302    void disableVertexProfile()
     303    {
     304        cgGLDisableProfile(_vertexProfile);
     305    }
     306
     307    void enableFragmentProfile()
     308    {
     309        cgGLEnableProfile(_fragmentProfile);
     310    }
     311
     312    void disableFragmentProfile()
     313    {
     314        cgGLDisableProfile(_fragmentProfile);
     315    }
     316
     317    static CGcontext getCgContext()
     318    {
     319        return _cgContext;
     320    }
     321
     322    std::string _vpFile;
     323    std::string _fpFile;
     324
     325    ParameterHashmap _vpParams;
     326    ParameterHashmap _fpParams;
    321327
    322328    CGprofile _vertexProfile;
    323329    CGprofile _fragmentProfile;
    324     std::string _vpFile;
     330
    325331    CGprogram _cgVP;
    326     std::string _fpFile;
    327332    CGprogram _cgFP;
    328     ParameterHashmap _vpParams;
    329     ParameterHashmap _fpParams;
    330333
    331334    static CGprofile _defaultVertexProfile;
     
    333336    static CGcontext _cgContext;
    334337
    335 private:
    336338    static CGprogram
    337339    loadCgSourceProgram(CGcontext context, const char *filename,
  • trunk/packages/vizservers/nanovis/StdVertexShader.cpp

    r3612 r3630  
    44 *
    55 */
     6#include <vrmath/Vector4f.h>
     7
    68#include "StdVertexShader.h"
    79
     10using namespace vrmath;
    811using namespace nv;
    912
     
    1922void StdVertexShader::init()
    2023{
    21     loadVertexProgram("vertex_std.cg", "main");
     24    loadVertexProgram("vertex_std.cg");
    2225}
    2326
    24 void StdVertexShader::bind(float *mvp, float *mvInv)
     27void StdVertexShader::bind(const Vector4f& objPlaneS,
     28                           const Vector4f& objPlaneT,
     29                           const Vector4f& objPlaneR,
     30                           float *mvp, float *mvInv)
    2531{
    2632    if (mvp != NULL) {
    2733        setVPMatrixParameterf("modelViewProjMatrix", mvp);
    2834    } else {
    29         setGLStateMatrixVPParameter("modelViewProjMatrix", MODELVIEW_PROJECTION_MATRIX);
     35        setGLStateMatrixVPParameter("modelViewProjMatrix",
     36                                    MODELVIEW_PROJECTION_MATRIX);
    3037    }
    3138    if (mvInv != NULL) {
    3239        setVPMatrixParameterf("modelViewInv", mvInv);
    3340    } else {
    34         setGLStateMatrixVPParameter("modelViewInv", MODELVIEW_MATRIX, MATRIX_INVERSE);
     41        setGLStateMatrixVPParameter("modelViewInv",
     42                                    MODELVIEW_MATRIX, MATRIX_INVERSE);
    3543    }
     44
     45    setVPParameter4f("light0Position", 1, 1, 1, 1);
     46    setVPParameter4f("objPlaneS",
     47                     objPlaneS.x, objPlaneS.y, objPlaneS.z, objPlaneS.w);
     48    setVPParameter4f("objPlaneT",
     49                     objPlaneT.x, objPlaneT.y, objPlaneT.z, objPlaneT.w);
     50    setVPParameter4f("objPlaneR",
     51                     objPlaneR.x, objPlaneR.y, objPlaneR.z, objPlaneR.w);
    3652
    3753    Shader::bind();
  • trunk/packages/vizservers/nanovis/StdVertexShader.h

    r3612 r3630  
    66#ifndef NV_STD_VERTEX_SHADER_H
    77#define NV_STD_VERTEX_SHADER_H
     8
     9#include <vrmath/Vector4f.h>
    810
    911#include "Shader.h"
     
    1820    virtual ~StdVertexShader();
    1921
    20     virtual void bind(float *mvp = NULL, float *mvInv = NULL);
     22    virtual void bind(const vrmath::Vector4f& objPlaneS,
     23                      const vrmath::Vector4f& objPlaneT,
     24                      const vrmath::Vector4f& objPlaneR,
     25                      float *mvp = NULL, float *mvInv = NULL);
    2126
    2227    virtual void unbind()
  • trunk/packages/vizservers/nanovis/Unirect.h

    r3613 r3630  
    1313
    1414#include <rappture.h>
     15
     16#include <vrmath/Vector3f.h>
    1517
    1618#include "Trace.h"
     
    197199    }
    198200
     201    void getBounds(vrmath::Vector3f& bboxMin,
     202                   vrmath::Vector3f& bboxMax) const
     203    {
     204        bboxMin.set(_xMin, _yMin, _zMin);
     205        bboxMax.set(_xMax, _yMax, _zMax);
     206    }
     207
    199208    const float *SaveValues()
    200209    {
     
    352361    }
    353362
     363    void getBounds(vrmath::Vector3f& bboxMin,
     364                   vrmath::Vector3f& bboxMax) const
     365    {
     366        bboxMin.set(_xMin, _yMin, 0);
     367        bboxMax.set(_xMax, _yMax, 0);
     368    }
     369
    354370    float *transferValues()
    355371    {
  • trunk/packages/vizservers/nanovis/VelocityArrowsSlice.cpp

    r3612 r3630  
    1919#include "nanovis.h"
    2020#include "VelocityArrowsSlice.h"
     21#include "Volume.h"
    2122#include "Shader.h"
    2223#include "Camera.h"
     
    3839VelocityArrowsSlice::VelocityArrowsSlice() :
    3940    _vectorFieldGraphicsID(0),
    40     _vfXscale(0),
    41     _vfYscale(0),
    42     _vfZscale(0),
    4341    _slicePos(0.5f),
    44     _axis(2),
     42    _axis(AXIS_Z),
    4543    _fbo(0),
    4644    _tex(0),
     
    5755    _maxVelocityScale(1, 1, 1),
    5856    _arrowColor(1, 1, 0),
    59     _enabled(false),
     57    _visible(false),
    6058    _dirty(true),
    6159    _vertexBufferGraphicsID(0),
     
    6361    _renderMode(LINES)
    6462{
    65     axis(2);
    66 
    67     _queryVelocityFP.loadFragmentProgram("queryvelocity.cg", "main");
    68 
    69     _particleShader.loadVertexProgram("velocityslicevp.cg", "vpmain");
    70     _particleShader.loadFragmentProgram("velocityslicefp.cg", "fpmain");
     63    setSliceAxis(AXIS_Z);
     64
     65    _queryVelocityFP.loadFragmentProgram("queryvelocity.cg");
     66
     67    _particleShader.loadVertexProgram("velocityslicevp.cg");
     68    _particleShader.loadFragmentProgram("velocityslicefp.cg");
    7169
    7270    createRenderTarget();
     
    175173}
    176174
    177 void VelocityArrowsSlice::axis(int axis)
     175void VelocityArrowsSlice::setSliceAxis(FlowSliceAxis axis)
    178176{
    179177    _axis = axis;
    180178    switch (_axis) {
    181     case 0:
     179    case AXIS_X:
    182180        _projectionVector.x = 0;
    183181        _projectionVector.y = 1;
    184182        _projectionVector.z = 1;
    185183        break;
    186     case 1 :
     184    case AXIS_Y:
    187185        _projectionVector.x = 1;
    188186        _projectionVector.y = 0;
    189187        _projectionVector.z = 1;
    190188        break;
    191     case 2:
     189    case AXIS_Z:
    192190        _projectionVector.x = 1;
    193191        _projectionVector.y = 1;
     
    200198void VelocityArrowsSlice::queryVelocity()
    201199{
    202     if (!_enabled) return;
    203 
    204200    glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
    205201    int fboOrig;
     
    301297void VelocityArrowsSlice::render()
    302298{
    303     if (!_enabled)
     299    if (!_visible)
    304300        return;
    305301
     
    310306    }
    311307
    312     TRACE("_vf: %g %g %g", _vfXscale,_vfYscale, _vfZscale);
     308    TRACE("_scale: %g %g %g", _scale.x, _scale.y, _scale.z);
    313309    TRACE("_maxVelocityScale: %g %g %g",
    314310          _maxVelocityScale.x, _maxVelocityScale.y, _maxVelocityScale.z);
     
    319315    glPushMatrix();
    320316
    321     glScalef(_vfXscale,_vfYscale, _vfZscale);
    322     glTranslatef(-0.5f, -0.5f, -0.5f);
     317    glTranslatef(_origin.x, _origin.y, _origin.z);
     318    glScalef(_scale.x, _scale.y, _scale.z);
    323319
    324320    if (_renderMode == LINES) {
     
    422418        _particleShader.setFPTextureParameter("arrows", _arrowsTex->id());
    423419        _particleShader.setVPParameter1f("tanHalfFOV",
    424                                          tan(NanoVis::getCamera()->fov() * 0.5) * NanoVis::winHeight * 0.5);
     420                                         tan(NanoVis::getCamera()->getFov() * 0.5) * NanoVis::winHeight * 0.5);
    425421        _particleShader.setGLStateMatrixVPParameter("modelview",
    426422                                                    Shader::MODELVIEW_MATRIX,
     
    457453
    458454void
    459 VelocityArrowsSlice::setVectorField(unsigned int vfGraphicsID, const Vector3f& origin,
    460                                     float xScale, float yScale, float zScale, float max)
    461 {
    462     _vectorFieldGraphicsID = vfGraphicsID;
    463     _vfXscale = xScale;
    464     _vfYscale = yScale;
    465     _vfZscale = zScale;
     455VelocityArrowsSlice::setVectorField(Volume *volume)
     456{
     457    _vectorFieldGraphicsID = volume->textureID();
     458    Vector3f bmin, bmax;
     459    volume->getBounds(bmin, bmax);
     460    _origin = bmin;
     461    _scale.set(bmax.x-bmin.x, bmax.y-bmin.y, bmax.z-bmin.z);
    466462
    467463    _dirty = true;
     
    470466void VelocityArrowsSlice::computeSamplingTicks()
    471467{
    472     if (_vfXscale < _vfYscale) {
    473         if (_vfXscale < _vfZscale || _vfZscale == 0.0) {
    474             // vfXscale
     468    if (_scale.x < _scale.y) {
     469        if (_scale.x < _scale.z || _scale.z == 0.0) {
     470            // _scale.x
    475471            _tickCountX = _tickCountForMinSizeAxis;
    476472
    477             float step = _vfXscale / (_tickCountX + 1);
    478 
    479             _tickCountY = (int)(_vfYscale/step);
    480             _tickCountZ = (int)(_vfZscale/step);
     473            float step = _scale.x / (_tickCountX + 1);
     474            _tickCountY = (int)(_scale.y/step);
     475            _tickCountZ = (int)(_scale.z/step);
    481476        } else {
    482             // vfZscale
     477            // _scale.z
    483478            _tickCountZ = _tickCountForMinSizeAxis;
    484479
    485             float step = _vfZscale / (_tickCountZ + 1);
    486             _tickCountX = (int)(_vfXscale/step);
    487             _tickCountY = (int)(_vfYscale/step);
     480            float step = _scale.z / (_tickCountZ + 1);
     481            _tickCountX = (int)(_scale.x/step);
     482            _tickCountY = (int)(_scale.y/step);
    488483        }
    489484    } else {
    490         if (_vfYscale < _vfZscale || _vfZscale == 0.0) {
    491             // _vfYscale
     485        if (_scale.y < _scale.z || _scale.z == 0.0) {
     486            // _scale.y
    492487            _tickCountY = _tickCountForMinSizeAxis;
    493488
    494             float step = _vfYscale / (_tickCountY + 1);
    495             _tickCountX = (int)(_vfXscale/step);
    496             _tickCountZ = (int)(_vfZscale/step);
     489            float step = _scale.y / (_tickCountY + 1);
     490            _tickCountX = (int)(_scale.x/step);
     491            _tickCountZ = (int)(_scale.z/step);
    497492        } else {
    498             // vfZscale
     493            // _scale.z
    499494            _tickCountZ = _tickCountForMinSizeAxis;
    500495
    501             float step = _vfZscale / (_tickCountZ + 1);
    502             _tickCountX = (int)(_vfXscale/step);
    503             _tickCountY = (int)(_vfYscale/step);
     496            float step = _scale.z / (_tickCountZ + 1);
     497            _tickCountX = (int)(_scale.x/step);
     498            _tickCountY = (int)(_scale.y/step);
    504499        }
    505500    }
  • trunk/packages/vizservers/nanovis/VelocityArrowsSlice.h

    r3613 r3630  
    1111#include <vrmath/Vector3f.h>
    1212
     13#include "FlowTypes.h"
     14#include "Volume.h"
    1315#include "Texture2D.h"
    1416#include "Shader.h"
     
    2830    ~VelocityArrowsSlice();
    2931
    30     void setVectorField(unsigned int vfGraphicsID, const vrmath::Vector3f& origin,
    31                         float xScale, float yScale, float zScale, float max);
     32    void setVectorField(Volume *volume);
    3233
    33     void axis(int axis);
     34    void setSliceAxis(FlowSliceAxis axis);
    3435
    35     int axis() const
     36    int getSliceAxis() const
    3637    {
    3738        return _axis;
    3839    }
    3940
    40     void slicePos(float pos)
     41    void setSlicePosition(float pos)
    4142    {
    4243        _slicePos = pos;
     
    4445    }
    4546
    46     float slicePos() const
     47    float getSlicePosition() const
    4748    {
    4849        return _slicePos;
    4950    }
    5051
    51     void queryVelocity();
    52 
    5352    void render();
    5453
    55     void enabled(bool enabled)
     54    void visible(bool visible)
    5655    {
    57         _enabled = enabled;
     56        _visible = visible;
    5857    }
    5958
    60     bool enabled() const
     59    bool visible() const
    6160    {
    62         return _enabled;
     61        return _visible;
    6362    }
    6463
     
    9089
    9190private:
     91    void queryVelocity();
     92
    9293    void createRenderTarget();
    9394
     
    9596
    9697    unsigned int _vectorFieldGraphicsID;
    97     float _vfXscale;
    98     float _vfYscale;
    99     float _vfZscale;
     98    vrmath::Vector3f _origin;
     99    vrmath::Vector3f _scale;
     100
    100101    float _slicePos;
    101     int _axis;
     102    FlowSliceAxis _axis;
    102103
    103104    unsigned int _fbo;
     
    124125    vrmath::Vector3f _arrowColor;
    125126
    126     bool _enabled;
     127    bool _visible;
    127128    bool _dirty;
    128129    bool _dirtySamplingPosition;
  • trunk/packages/vizservers/nanovis/Volume.cpp

    r3611 r3630  
    3131double Volume::valueMax = 1.0;
    3232
    33 Volume::Volume(float x, float y, float z,
    34                int w, int h, int d,
     33Volume::Volume(int w, int h, int d,
    3534               int n, float *data,
    3635               double v0, double v1, double nonZeroMin) :
     
    5049    _nonZeroMin(nonZeroMin),
    5150    _tex(NULL),
    52     _location(x, y, z),
     51    _position(0,0,0),
     52    _scale(1,1,1),
    5353    _numSlices(512),
    5454    _enabled(true),
     
    6565    int fcount = _width * _height * _depth * _numComponents;
    6666    _data = new float[fcount];
    67     if (data != NULL) {
    68         TRACE("data is copied");
    69         memcpy(_data, data, fcount * sizeof(float));
    70         _tex->initialize(_data);
    71     } else {
    72         TRACE("data is null");
    73         memset(_data, 0, sizeof(_width * _height * _depth * _numComponents *
    74                                 sizeof(float)));
    75         _tex->initialize(_data);
    76     }
     67    memcpy(_data, data, fcount * sizeof(float));
     68    _tex->initialize(_data);
    7769
    7870    _id = _tex->id();
     
    8375    //The default location of cut plane is in the middle of the data.
    8476    _plane.clear();
    85     addCutplane(1, 0.5f);
    86     addCutplane(2, 0.5f);
    87     addCutplane(3, 0.5f);
     77    addCutplane(CutPlane::X_AXIS, 0.5f);
     78    addCutplane(CutPlane::Y_AXIS, 0.5f);
     79    addCutplane(CutPlane::Z_AXIS, 0.5f);
    8880
    8981    TRACE("Leave");
     
    9890}
    9991
    100 void Volume::getWorldSpaceBounds(Vector3f& bboxMin, Vector3f& bboxMax) const
     92void Volume::setData(float *data, double v0, double v1, double nonZeroMin)
    10193{
    102     Vector3f scale = getPhysicalScaling();
     94    int fcount = _width * _height * _depth * _numComponents;
     95    memcpy(_data, data, fcount * sizeof(float));
     96    _tex->update(_data);
     97    wAxis.setRange(v0, v1);
     98    _nonZeroMin = nonZeroMin;
     99    updatePending = true;
     100}
    103101
    104     Matrix4x4d mat;
    105     mat.makeTranslation(_location);
    106     Matrix4x4d mat2;
    107     mat2.makeScale(scale);
    108 
    109     mat.multiply(mat2);
    110 
    111     bboxMin.set(FLT_MAX, FLT_MAX, FLT_MAX);
    112     bboxMax.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    113 
    114     Vector3f modelMin(0, 0, 0);
    115     Vector3f modelMax(1, 1, 1);
    116 
    117     Vector4f bvert[8];
    118     bvert[0] = Vector4f(modelMin.x, modelMin.y, modelMin.z, 1);
    119     bvert[1] = Vector4f(modelMax.x, modelMin.y, modelMin.z, 1);
    120     bvert[2] = Vector4f(modelMin.x, modelMax.y, modelMin.z, 1);
    121     bvert[3] = Vector4f(modelMin.x, modelMin.y, modelMax.z, 1);
    122     bvert[4] = Vector4f(modelMax.x, modelMax.y, modelMin.z, 1);
    123     bvert[5] = Vector4f(modelMax.x, modelMin.y, modelMax.z, 1);
    124     bvert[6] = Vector4f(modelMin.x, modelMax.y, modelMax.z, 1);
    125     bvert[7] = Vector4f(modelMax.x, modelMax.y, modelMax.z, 1);
    126 
    127     for (int i = 0; i < 8; i++) {
    128         Vector4f worldVert = mat.transform(bvert[i]);
    129         if (worldVert.x < bboxMin.x) bboxMin.x = worldVert.x;
    130         if (worldVert.x > bboxMax.x) bboxMax.x = worldVert.x;
    131         if (worldVert.y < bboxMin.y) bboxMin.y = worldVert.y;
    132         if (worldVert.y > bboxMax.y) bboxMax.y = worldVert.y;
    133         if (worldVert.z < bboxMin.z) bboxMin.z = worldVert.z;
    134         if (worldVert.z > bboxMax.z) bboxMax.z = worldVert.z;
    135     }
     102void Volume::getBounds(Vector3f& bboxMin, Vector3f& bboxMax) const
     103{
     104    bboxMin.set(xAxis.min(), yAxis.min(), zAxis.min());
     105    bboxMax.set(xAxis.max(), yAxis.max(), zAxis.max());
    136106}
  • trunk/packages/vizservers/nanovis/Volume.h

    r3613 r3630  
    2121namespace nv {
    2222
    23 struct CutPlane {
    24     /// orientation - 1: xy slice, 2: yz slice, 3: xz slice
    25     int orient;
    26     float offset;       ///< normalized offset [0,1] in the volume
    27     bool enabled;
    28 
    29     CutPlane(int _orient, float _offset) :
     23class CutPlane {
     24public:
     25    enum Axis {
     26        X_AXIS = 1,
     27        Y_AXIS = 2,
     28        Z_AXIS = 3
     29    };
     30
     31    CutPlane(Axis _orient, float _offset) :
    3032        orient(_orient),
    3133        offset(_offset),
     
    3335    {
    3436    }
     37
     38    Axis orient;
     39    float offset;       ///< normalized offset [0,1] in the volume
     40    bool enabled;
    3541};
    3642
     
    5258     * each axis.  Sample spacing may differ between X, Y and Z
    5359     *
    54      * \param x X location
    55      * \param y Y location
    56      * \param z Z location
    5760     * \param width Number of samples in X
    5861     * \param height Number of samples in Y
     
    6467     * \param nonZeroMin Scalar minimum which is greater than zero
    6568     */
    66     Volume(float x, float y, float z,
    67            int width, int height, int depth,
     69    Volume(int width, int height, int depth,
    6870           int numComponents,
    6971           float *data,
     
    98100    }
    99101
    100     void location(const vrmath::Vector3f& loc)
    101     {
    102         _location = loc;
    103     }
    104 
    105     vrmath::Vector3f location() const
    106     {
    107         return _location;
    108     }
    109 
    110102    int isosurface() const
    111103    {
     
    132124        return _volumeType;
    133125    }
     126
     127    void setData(float *data, double v0, double v1, double nonZeroMin);
    134128
    135129    const float *data() const
     
    155149    // methods related to cutplanes
    156150    /// add a plane and returns its index
    157     int addCutplane(int orientation, float location);
     151    int addCutplane(CutPlane::Axis orientation, float location);
    158152
    159153    void enableCutplane(int index);
     
    161155    void disableCutplane(int index);
    162156
    163     void moveCutplane(int index, float location);
     157    void setCutplanePosition(int index, float location);
    164158
    165159    CutPlane *getCutplane(int index);
     
    282276
    283277    void getOutlineColor(float *rgb);
    284 
    285     vrmath::Vector3f getPhysicalScaling() const
    286     {
    287         vrmath::Vector3f scale;
    288         scale.x = 1;
    289         scale.y = yAxis.length() / xAxis.length();
    290         scale.z = zAxis.length() / xAxis.length();
    291         return scale;
    292     }
    293 
    294     void getWorldSpaceBounds(vrmath::Vector3f& bboxMin,
    295                              vrmath::Vector3f& bboxMax) const;
     278   
     279    void setPosition(const vrmath::Vector3f& pos)
     280    {
     281        _position = pos;
     282    }
     283
     284    const vrmath::Vector3f& getPosition() const
     285    {
     286        return _position;
     287    }
     288
     289    void setScale(const vrmath::Vector3f& scale)
     290    {
     291        _scale = scale;
     292    }
     293
     294    const vrmath::Vector3f& getScale() const
     295    {
     296        return _scale;
     297    }
     298
     299    void getBounds(vrmath::Vector3f& bboxMin,
     300                   vrmath::Vector3f& bboxMax) const;
    296301 
    297302    double sampleDistanceX() const
     
    370375    /**
    371376     * The scale multiplied to the opacity assigned by the
    372      * transfer function. Rule of thumb: higher opacity_scale
    373      * the object is to appear like plastic
     377     * transfer function.
    374378     */
    375379    float _opacityScale;
     
    387391    Texture3D *_tex;            ///< OpenGL texture storing the volume
    388392
    389     vrmath::Vector3f _location;
     393    vrmath::Vector3f _position;
     394    vrmath::Vector3f _scale;
    390395
    391396    /**
     
    403408
    404409inline int
    405 Volume::addCutplane(int orientation, float location)
     410Volume::addCutplane(CutPlane::Axis orientation, float location)
    406411{
    407412    _plane.push_back(CutPlane(orientation, location));
     
    424429
    425430inline void
    426 Volume::moveCutplane(int index, float location)
     431Volume::setCutplanePosition(int index, float position)
    427432{
    428433    //assert(index < plane.size());
    429     _plane[index].offset = location;
     434    _plane[index].offset = position;
    430435}
    431436
  • trunk/packages/vizservers/nanovis/VolumeInterpolator.cpp

    r3611 r3630  
    3232void VolumeInterpolator::start()
    3333{
    34     if (_volumes.size() > 0) {
     34    if (!_volumes.empty()) {
    3535        TRACE("Volume Interpolation Started");
    3636        _started = true;
     
    128128VolumeInterpolator::addVolume(Volume *volume)
    129129{
    130     if (_volumes.size() != 0) {
     130    if (!_volumes.empty()) {
    131131        if (_volumes[0]->width() != volume->width() ||
    132132            _volumes[0]->height() != volume->height() ||   
     
    140140        _numComponents = volume->numComponents();
    141141        _numBytes = _dataCount * _numComponents * sizeof(float);
    142         Vector3f loc = volume->location();
    143         _volume = new Volume(loc.x, loc.y, loc.z,
    144                              volume->width(),
     142        _volume = new Volume(volume->width(),
    145143                             volume->height(),
    146144                             volume->depth(),
     
    151149                             volume->nonZeroMin());
    152150
    153         _volume->numSlices(256-1);
     151        _volume->setPosition(volume->getPosition());
     152        _volume->setScale(volume->getScale());
    154153        _volume->disableCutplane(0);
    155154        _volume->disableCutplane(1);
     
    163162        _volume->opacityScale(volume->opacityScale());
    164163        _volume->isosurface(0);
    165         TRACE("VOL : location %f %f %f\n\tid : %s", loc.x, loc.y, loc.z,
    166                volume->name());
    167164    }
    168     _volumes.push_back(_volume);
    169     TRACE("a Volume[%s] is added to VolumeInterpolator", volume->name());
     165    _volumes.push_back(volume);
     166    TRACE("Volume \"%s\" is added to VolumeInterpolator", volume->name());
    170167}
    171168
     
    173170{
    174171    return _volume;
    175     //return _volumes[0];
    176172}
  • trunk/packages/vizservers/nanovis/VolumeInterpolator.h

    r3613 r3630  
    4040private:
    4141    Volume *_volume;
    42 
    43     std::vector<Volume*> _volumes;
     42    std::vector<Volume *> _volumes;
    4443
    4544    double _interval;
  • trunk/packages/vizservers/nanovis/VolumeRenderer.cpp

    r3612 r3630  
    2222
    2323#include <vrmath/Vector3f.h>
     24#include <vrmath/Vector4f.h>
    2425#include <vrmath/Matrix4x4d.h>
     26#include <vrmath/BBox.h>
    2527
    2628#include "nanovis.h"
     
    5456{
    5557    _cutplaneShader = new Shader();
    56     _cutplaneShader->loadVertexProgram("cutplane_vp.cg", "main");
    57     _cutplaneShader->loadFragmentProgram("cutplane_fp.cg", "main");
     58    _cutplaneShader->loadVertexProgram("cutplane_vp.cg");
     59    _cutplaneShader->loadFragmentProgram("cutplane_fp.cg");
    5860
    5961    //standard vertex program
     
    6769    //A sim has S, P, D, SS orbitals. thus a full rendering requires 4 zincblende orbital volumes.
    6870    //A zincblende orbital volume is decomposed into 2 "interlocking" cubic 4-component volumes and passed to the shader.
    69     //We render each orbital with a independent transfer functions then blend the result.
     71    //We render each orbital with independent transfer functions then blend the result.
    7072    //
    7173    //The engine is already capable of rendering multiple volumes and combine them. Thus, we just invoke this shader on
     
    130132    size_t *actual_slices = new size_t[volumes.size()];
    131133    float *z_steps = new float[volumes.size()];
     134    float *sampleRatios = new float[volumes.size()];
     135    Vector4f *objPlaneS = new Vector4f[volumes.size()];
     136    Vector4f *objPlaneT = new Vector4f[volumes.size()];
     137    Vector4f *objPlaneR = new Vector4f[volumes.size()];
    132138
    133139    TRACE("start loop %d", volumes.size());
     
    143149        }
    144150
    145         //volume start location
    146         Vector3f volPos = volume->location();
    147         Vector3f volScaling = volume->getPhysicalScaling();
     151        // Get any additional transforms on Volume
     152        Vector3f volPos = volume->getPosition();
     153        Vector3f volScale = volume->getScale();
     154        // Get world coords of volume bbox
     155        double x0 = volume->xAxis.min();
     156        double y0 = volume->yAxis.min();
     157        double z0 = volume->zAxis.min();
     158        double x1 = volume->xAxis.max();
     159        double y1 = volume->yAxis.max();
     160        double z1 = volume->zAxis.max();
     161        Vector3f worldMin(x0, y0, z0);
     162        Vector3f worldMax(x1, y1, z1);
     163
     164        float edgeLengthX = volume->xAxis.length();
     165        float edgeLengthY = volume->yAxis.length();
     166        float edgeLengthZ = volume->zAxis.length();
     167        // Texgen planes
     168        objPlaneS[i].set(1./edgeLengthX, 0, 0, -volume->xAxis.min()/edgeLengthX);
     169        objPlaneT[i].set(0, 1./edgeLengthY, 0, -volume->yAxis.min()/edgeLengthY);
     170        objPlaneR[i].set(0, 0, 1./edgeLengthZ, -volume->zAxis.min()/edgeLengthZ);
     171
     172        Matrix4x4d model_view_no_trans, model_view_trans;
     173        Matrix4x4d model_view_no_trans_inverse, model_view_trans_inverse;
     174
     175        //initialize volume plane with world coordinates
     176        nv::Plane volume_planes[6];
     177        volume_planes[0].setCoeffs( 1,  0,  0, -x0);
     178        volume_planes[1].setCoeffs(-1,  0,  0,  x1);
     179        volume_planes[2].setCoeffs( 0,  1,  0, -y0);
     180        volume_planes[3].setCoeffs( 0, -1,  0,  y1);
     181        volume_planes[4].setCoeffs( 0,  0,  1, -z0);
     182        volume_planes[5].setCoeffs( 0,  0, -1,  z1);
    148183
    149184        TRACE("VOL POS: %g %g %g",
    150185              volPos.x, volPos.y, volPos.z);
    151186        TRACE("VOL SCALE: %g %g %g",
    152               volScaling.x, volScaling.y, volScaling.z);
    153 
    154         double x0 = 0;
    155         double y0 = 0;
    156         double z0 = 0;
    157 
    158         Matrix4x4d model_view_no_trans, model_view_trans;
    159         Matrix4x4d model_view_no_trans_inverse, model_view_trans_inverse;
    160 
    161         //initialize volume plane with world coordinates
    162         nv::Plane volume_planes[6];
    163         volume_planes[0].setCoeffs( 1,  0,  0, -x0);
    164         volume_planes[1].setCoeffs(-1,  0,  0,  x0+1);
    165         volume_planes[2].setCoeffs( 0,  1,  0, -y0);
    166         volume_planes[3].setCoeffs( 0, -1,  0,  y0+1);
    167         volume_planes[4].setCoeffs( 0,  0,  1, -z0);
    168         volume_planes[5].setCoeffs( 0,  0, -1,  z0+1);
     187              volScale.x, volScale.y, volScale.z);
    169188
    170189        //get modelview matrix with no translation
    171190        glPushMatrix();
    172         glScalef(volScaling.x, volScaling.y, volScaling.z);
     191        glScalef(volScale.x, volScale.y, volScale.z);
    173192
    174193        glEnable(GL_DEPTH_TEST);
     
    185204        glPushMatrix();
    186205        glTranslatef(volPos.x, volPos.y, volPos.z);
    187         glScalef(volScaling.x, volScaling.y, volScaling.z);
     206        glScalef(volScale.x, volScale.y, volScale.z);
    188207
    189208        GLdouble mv_trans[16];
     
    200219            float olcolor[3];
    201220            volume->getOutlineColor(olcolor);
    202             drawBoundingBox(x0, y0, z0, x0+1, y0+1, z0+1,
    203                 (double)olcolor[0], (double)olcolor[1], (double)olcolor[2],
    204                 1.5);
     221            drawBoundingBox(x0, y0, z0, x1, y1, z1,
     222                            olcolor[0], olcolor[1], olcolor[2],
     223                            1.5);
    205224        }
    206225        glPopMatrix();
     
    212231            volume_planes[j].transform(model_view_no_trans);
    213232        }
    214         double eyeMinX, eyeMaxX, eyeMinY, eyeMaxY, zNear, zFar;
    215         getEyeSpaceBounds(model_view_no_trans,
    216                           eyeMinX, eyeMaxX,
    217                           eyeMinY, eyeMaxY,
    218                           zNear, zFar);
     233        Vector3f eyeMin, eyeMax;
     234        double zNear, zFar;
     235        getEyeSpaceBounds(worldMin, worldMax,
     236                          model_view_no_trans,
     237                          eyeMin, eyeMax);
     238        zNear = eyeMax.z;
     239        zFar = eyeMin.z;
    219240
    220241        //compute actual rendering slices
     
    236257
    237258        TRACE("near: %g far: %g eye space bounds: (%g,%g)-(%g,%g) z_step: %g slices: %d",
    238               zNear, zFar, eyeMinX, eyeMaxX, eyeMinY, eyeMaxY, z_step, n_actual_slices);
     259              zNear, zFar, eyeMin.x, eyeMax.x, eyeMin.y, eyeMax.y, z_step, n_actual_slices);
     260
     261        // Compute opacity correction sample ratios
     262        float defDist = z_step == 0.0f ? 1.0 : z_step;
     263        float sampleDistX = (volume->width() > 1) ? edgeLengthX / (volume->width()-1) : defDist;
     264        float sampleDistY = (volume->height() > 1) ? edgeLengthY / (volume->height()-1) : defDist;
     265        float sampleDistZ = (volume->depth() > 1) ? edgeLengthZ / (volume->depth()-1) : defDist;
     266        sampleDistX *= volScale.x;
     267        sampleDistY *= volScale.y;
     268        sampleDistZ *= volScale.z;
     269        BBox voxelIn, voxelOut;
     270        voxelIn.min.set(0,0,0);
     271        voxelIn.max.set(sampleDistX, sampleDistY, sampleDistZ);
     272        getEyeSpaceBounds(voxelIn.min, voxelIn.max, model_view_no_trans, voxelOut.min, voxelOut.max);
     273        sampleRatios[i] = z_step / (voxelOut.max.z - voxelOut.min.z);
    239274
    240275        Vector4f vert1, vert2, vert3, vert4;
     
    249284                continue;
    250285            }
     286            Vector4f texcoord1, texcoord2, texcoord3, texcoord4;
    251287            float offset = volume->getCutplane(j)->offset;
    252288            int axis = volume->getCutplane(j)->orient;
    253289
    254290            switch (axis) {
    255             case 1:
    256                 vert1 = Vector4f(offset, 0, 0, 1);
    257                 vert2 = Vector4f(offset, 1, 0, 1);
    258                 vert3 = Vector4f(offset, 1, 1, 1);
    259                 vert4 = Vector4f(offset, 0, 1, 1);
     291            case CutPlane::X_AXIS: // YZ plane
     292                vert1 = Vector4f(x0 + offset * (x1 - x0), y0, z0, 1);
     293                vert2 = Vector4f(x0 + offset * (x1 - x0), y1, z0, 1);
     294                vert3 = Vector4f(x0 + offset * (x1 - x0), y1, z1, 1);
     295                vert4 = Vector4f(x0 + offset * (x1 - x0), y0, z1, 1);
     296                texcoord1 = Vector4f(offset, 0, 0, 1);
     297                texcoord2 = Vector4f(offset, 1, 0, 1);
     298                texcoord3 = Vector4f(offset, 1, 1, 1);
     299                texcoord4 = Vector4f(offset, 0, 1, 1);
    260300                break;
    261             case 2:
    262                 vert1 = Vector4f(0, offset, 0, 1);
    263                 vert2 = Vector4f(1, offset, 0, 1);
    264                 vert3 = Vector4f(1, offset, 1, 1);
    265                 vert4 = Vector4f(0, offset, 1, 1);
     301            case CutPlane::Y_AXIS: // XZ plane
     302                vert1 = Vector4f(x0, y0 + offset * (y1 - y0), z0, 1);
     303                vert2 = Vector4f(x1, y0 + offset * (y1 - y0), z0, 1);
     304                vert3 = Vector4f(x1, y0 + offset * (y1 - y0), z1, 1);
     305                vert4 = Vector4f(x0, y0 + offset * (y1 - y0), z1, 1);
     306                texcoord1 = Vector4f(0, offset, 0, 1);
     307                texcoord2 = Vector4f(1, offset, 0, 1);
     308                texcoord3 = Vector4f(1, offset, 1, 1);
     309                texcoord4 = Vector4f(0, offset, 1, 1);
    266310                break;
    267             case 3:
     311            case CutPlane::Z_AXIS: // XY plane
    268312            default:
    269                 vert1 = Vector4f(0, 0, offset, 1);
    270                 vert2 = Vector4f(1, 0, offset, 1);
    271                 vert3 = Vector4f(1, 1, offset, 1);
    272                 vert4 = Vector4f(0, 1, offset, 1);
     313                vert1 = Vector4f(x0, y0, z0 + offset * (z1 - z0), 1);
     314                vert2 = Vector4f(x1, y0, z0 + offset * (z1 - z0), 1);
     315                vert3 = Vector4f(x1, y1, z0 + offset * (z1 - z0), 1);
     316                vert4 = Vector4f(x0, y1, z0 + offset * (z1 - z0), 1);
     317                texcoord1 = Vector4f(0, 0, offset, 1);
     318                texcoord2 = Vector4f(1, 0, offset, 1);
     319                texcoord3 = Vector4f(1, 1, offset, 1);
     320                texcoord4 = Vector4f(0, 1, offset, 1);
    273321                break;
    274322            }
    275 
    276             Vector4f texcoord1 = vert1;
    277             Vector4f texcoord2 = vert2;
    278             Vector4f texcoord3 = vert3;
    279             Vector4f texcoord4 = vert4;
    280323
    281324            _cutplaneShader->bind();
     
    285328            glPushMatrix();
    286329            glTranslatef(volPos.x, volPos.y, volPos.z);
    287             glScalef(volScaling.x, volScaling.y, volScaling.z);
     330            glScalef(volScale.x, volScale.y, volScale.z);
    288331            _cutplaneShader->setGLStateMatrixVPParameter("modelViewProjMatrix",
    289332                                                         Shader::MODELVIEW_PROJECTION_MATRIX);
     
    314357        // Initialize view-aligned quads with eye space bounds of
    315358        // volume
    316         vert1 = Vector4f(eyeMinX, eyeMinY, -0.5, 1);
    317         vert2 = Vector4f(eyeMaxX, eyeMinY, -0.5, 1);
    318         vert3 = Vector4f(eyeMaxX, eyeMaxY, -0.5, 1);
    319         vert4 = Vector4f(eyeMinX, eyeMaxY, -0.5, 1);
     359        vert1 = Vector4f(eyeMin.x, eyeMin.y, zFar, 1);
     360        vert2 = Vector4f(eyeMax.x, eyeMin.y, zFar, 1);
     361        vert3 = Vector4f(eyeMax.x, eyeMax.y, zFar, 1);
     362        vert4 = Vector4f(eyeMin.x, eyeMax.y, zFar, 1);
    320363
    321364        size_t counter = 0;
     
    345388
    346389            for (size_t k = 0; k < 6; k++) {
    347                 if (!poly->clip(volume_planes[k], true))
     390                if (!poly->clip(volume_planes[k], false))
    348391                    break;
    349392            }
     
    384427
    385428    for (size_t i = 0; i < total_rendered_slices; i++) {
    386         Volume *volume = NULL;
    387 
    388         int volume_index = slices[i].volumeId;
    389         int slice_index = slices[i].sliceId;
    390         ConvexPolygon *currentSlice = polys[volume_index][slice_index];
    391         float z_step = z_steps[volume_index];
    392 
    393         volume = volumes[volume_index];
    394 
    395         Vector3f volScaling = volume->getPhysicalScaling();
     429        int volIdx = slices[i].volumeId;
     430        int sliceIdx = slices[i].sliceId;
     431        ConvexPolygon *currentSlice = polys[volIdx][sliceIdx];
     432
     433        Volume *volume = volumes[volIdx];
     434        Vector3f volPos = volume->getPosition();
     435        Vector3f volScale = volume->getScale();
    396436
    397437        glPushMatrix();
    398         glScalef(volScaling.x, volScaling.y, volScaling.z);
    399 
    400         // FIXME: compute view-dependent volume sample distance
    401         double avgSampleDistance = 1.0 / pow(volume->width() * volScaling.x *
    402                                              volume->height() * volScaling.y *
    403                                              volume->depth() * volScaling.z, 1.0/3.0);
    404         float sampleRatio = z_step / avgSampleDistance;
     438        glTranslatef(volPos.x, volPos.y, volPos.z);
     439        glScalef(volScale.x, volScale.y, volScale.z);
    405440
    406441#ifdef notdef
    407         TRACE("shading slice: volume %s addr=%x slice=%d, volume=%d z_step=%g avgSD=%g",
    408               volume->name(), volume, slice_index, volume_index, z_step, avgSampleDistance);
     442        float z_step = z_steps[volIdx];
     443        TRACE("shading slice: volume %s addr=%x slice=%d, volume=%d z_step=%g sampleRatio=%g",
     444              volume->name(), volume, sliceIdx, volIdx, z_step, sampleRatios[volIdx]);
    409445#endif
    410         activateVolumeShader(volume, false, sampleRatio);
     446        activateVolumeShader(volume, objPlaneS[volIdx], objPlaneT[volIdx], objPlaneR[volIdx], false, sampleRatios[volIdx]);
    411447        glPopMatrix();
    412448
    413449        glBegin(GL_POLYGON);
    414         currentSlice->emit(true);
     450        currentSlice->emit(false);
    415451        glEnd();
    416452
     
    432468    delete[] actual_slices;
    433469    delete[] z_steps;
     470    delete[] objPlaneS;
     471    delete[] objPlaneT;
     472    delete[] objPlaneR;
     473    delete[] sampleRatios;
    434474    free(slices);
    435475}
     
    439479                                float x1, float y1, float z1,
    440480                                float r, float g, float b,
    441                                 float line_width)
     481                                float lineWidth)
    442482{
    443483    glPushAttrib(GL_ENABLE_BIT);
     
    451491
    452492    glColor4d(r, g, b, 1.0);
    453     glLineWidth(line_width);
     493    glLineWidth(lineWidth);
    454494
    455495    glBegin(GL_LINE_LOOP);
     
    494534
    495535void
    496 VolumeRenderer::activateVolumeShader(Volume *volume, bool sliceMode,
     536VolumeRenderer::activateVolumeShader(Volume *volume,
     537                                     Vector4f& objPlaneS,
     538                                     Vector4f& objPlaneT,
     539                                     Vector4f& objPlaneR,
     540                                     bool sliceMode,
    497541                                     float sampleRatio)
    498542{
    499543    //vertex shader
    500     _stdVertexShader->bind();
     544    _stdVertexShader->bind(objPlaneS, objPlaneT, objPlaneR);
    501545    TransferFunction *transferFunc  = volume->transferFunction();
    502546    if (volume->volumeType() == Volume::CUBIC) {
     
    514558}
    515559
    516 void VolumeRenderer::getEyeSpaceBounds(const Matrix4x4d& mv,
    517                                        double& xMin, double& xMax,
    518                                        double& yMin, double& yMax,
    519                                        double& zNear, double& zFar)
    520 {
    521     double x0 = 0;
    522     double y0 = 0;
    523     double z0 = 0;
    524     double x1 = 1;
    525     double y1 = 1;
    526     double z1 = 1;
    527 
    528     double zMin, zMax;
    529     xMin = DBL_MAX;
    530     xMax = -DBL_MAX;
    531     yMin = DBL_MAX;
    532     yMax = -DBL_MAX;
    533     zMin = DBL_MAX;
    534     zMax = -DBL_MAX;
    535 
    536     double vertex[8][4];
    537 
    538     vertex[0][0]=x0; vertex[0][1]=y0; vertex[0][2]=z0; vertex[0][3]=1.0;
    539     vertex[1][0]=x1; vertex[1][1]=y0; vertex[1][2]=z0; vertex[1][3]=1.0;
    540     vertex[2][0]=x0; vertex[2][1]=y1; vertex[2][2]=z0; vertex[2][3]=1.0;
    541     vertex[3][0]=x0; vertex[3][1]=y0; vertex[3][2]=z1; vertex[3][3]=1.0;
    542     vertex[4][0]=x1; vertex[4][1]=y1; vertex[4][2]=z0; vertex[4][3]=1.0;
    543     vertex[5][0]=x1; vertex[5][1]=y0; vertex[5][2]=z1; vertex[5][3]=1.0;
    544     vertex[6][0]=x0; vertex[6][1]=y1; vertex[6][2]=z1; vertex[6][3]=1.0;
    545     vertex[7][0]=x1; vertex[7][1]=y1; vertex[7][2]=z1; vertex[7][3]=1.0;
    546 
    547     for (int i = 0; i < 8; i++) {
    548         Vector4f eyeVert = mv.transform(Vector4f(vertex[i][0],
    549                                                  vertex[i][1],
    550                                                  vertex[i][2],
    551                                                  vertex[i][3]));
    552         if (eyeVert.x < xMin) xMin = eyeVert.x;
    553         if (eyeVert.x > xMax) xMax = eyeVert.x;
    554         if (eyeVert.y < yMin) yMin = eyeVert.y;
    555         if (eyeVert.y > yMax) yMax = eyeVert.y;
    556         if (eyeVert.z < zMin) zMin = eyeVert.z;
    557         if (eyeVert.z > zMax) zMax = eyeVert.z;
    558     }
    559 
    560     zNear = zMax;
    561     zFar = zMin;
    562 }
     560void VolumeRenderer::getEyeSpaceBounds(const Vector3f& worldMin,
     561                                       const Vector3f& worldMax,
     562                                       const Matrix4x4d& modelViewMatrix,
     563                                       Vector3f& eyeMin, Vector3f& eyeMax)
     564{
     565    BBox bbox(worldMin, worldMax);
     566
     567    bbox.transform(bbox, modelViewMatrix);
     568
     569    eyeMin = bbox.min;
     570    eyeMax = bbox.max;
     571}
  • trunk/packages/vizservers/nanovis/VolumeRenderer.h

    r3613 r3630  
    99#define NV_VOLUME_RENDERER_H
    1010
     11#include <vrmath/Vector3f.h>
     12#include <vrmath/Vector4f.h>
    1113#include <vrmath/Matrix4x4d.h>
    1214
     
    6163    void initShaders();
    6264
    63     void activateVolumeShader(Volume *vol, bool sliceMode, float sampleRatio);
     65    void activateVolumeShader(Volume *vol,
     66                              vrmath::Vector4f& objPlaneS,
     67                              vrmath::Vector4f& objPlaneT,
     68                              vrmath::Vector4f& objPlaneR,
     69                              bool sliceMode, float sampleRatio);
    6470
    6571    void deactivateVolumeShader();
    6672
    67     void drawBoundingBox(float x0, float y0, float z0,
    68                          float x1, float y1, float z1,
    69                          float r, float g, float b, float line_width);
     73    static void drawBoundingBox(float x0, float y0, float z0,
     74                                float x1, float y1, float z1,
     75                                float r, float g, float b, float line_width);
    7076
    71     void getEyeSpaceBounds(const vrmath::Matrix4x4d& mv,
    72                            double& xMin, double& xMax,
    73                            double& yMin, double& yMax,
    74                            double& zNear, double& zFar);
     77    static void getEyeSpaceBounds(const vrmath::Vector3f& worldMin,
     78                                  const vrmath::Vector3f& worldMax,
     79                                  const vrmath::Matrix4x4d& mv,
     80                                  vrmath::Vector3f& eyeMin,
     81                                  vrmath::Vector3f& eyeMax);
    7582
    7683    VolumeInterpolator *_volumeInterpolator;
  • trunk/packages/vizservers/nanovis/VtkReader.cpp

    r3611 r3630  
    488488    delete [] data;
    489489
    490     //
    491     // Center this new volume on the origin.
    492     //
    493     float dx0 = -0.5;
    494     float dy0 = -0.5*ly/lx;
    495     float dz0 = -0.5*lz/lx;
    496     if (volume) {
    497         volume->location(vrmath::Vector3f(dx0, dy0, dz0));
    498         TRACE("Set volume location to %g %g %g", dx0, dy0, dz0);
    499     }
    500490    return volume;
    501491}
  • trunk/packages/vizservers/nanovis/ZincBlendeReconstructor.cpp

    r3611 r3630  
    264264    cellSize.z = 0.25 / depth;
    265265
    266     zincBlendeVolume = new ZincBlendeVolume(origin.x, origin.y, origin.z,
    267                                             width, height, depth, 4,
     266    zincBlendeVolume = new ZincBlendeVolume(width, height, depth, 4,
    268267                                            fourAnionVolume, fourCationVolume,
    269268                                            vmin, vmax, nzero_min, cellSize);
     269
     270    zincBlendeVolume->xAxis.setRange(origin.x, origin.x + delta.x * (width-1));
     271    zincBlendeVolume->yAxis.setRange(origin.y, origin.y + delta.y * (height-1));
     272    zincBlendeVolume->zAxis.setRange(origin.z, origin.z + delta.z * (depth-1));
    270273
    271274    return zincBlendeVolume;
     
    342345    cellSize.z = 0.25 / depth;
    343346
    344     zincBlendeVolume = new ZincBlendeVolume(origin.x, origin.y, origin.z,
    345                                             width, height, depth, 4,
     347    zincBlendeVolume = new ZincBlendeVolume(width, height, depth, 4,
    346348                                            fourAnionVolume, fourCationVolume,
    347349                                            vmin, vmax, nzero_min, cellSize);
     350
     351    zincBlendeVolume->xAxis.setRange(origin.x, origin.x + delta.x * (width-1));
     352    zincBlendeVolume->yAxis.setRange(origin.y, origin.y + delta.y * (height-1));
     353    zincBlendeVolume->zAxis.setRange(origin.z, origin.z + delta.z * (depth-1));
    348354
    349355    return zincBlendeVolume;
  • trunk/packages/vizservers/nanovis/ZincBlendeVolume.cpp

    r3611 r3630  
    2424using namespace vrmath;
    2525
    26 ZincBlendeVolume::ZincBlendeVolume(float x, float y, float z,
    27                                    int w, int h, int d, int n,
     26ZincBlendeVolume::ZincBlendeVolume(int w, int h, int d, int n,
    2827                                   float *dataVolumeA, float *dataVolumeB,
    2928                                   double v0, double v1, double non_zeromin,
    3029                                   const Vector3f& cellSz) :
    31     Volume(x, y, z, w, h, d, n, dataVolumeA, v0, v1, non_zeromin),
     30    Volume(w, h, d, n, dataVolumeA, v0, v1, non_zeromin),
    3231    cellSize(cellSz)
    3332{
     
    4948ZincBlendeVolume::~ZincBlendeVolume()
    5049{
    51     // This data will be deleted in a destrutor of Volume class
    52     //if (zincblende_tex[0])
    53     //  delete zincblende_tex[0];
     50    // First texture will be deleted in ~Volume()
    5451    if (zincblendeTex[1])
    5552        delete zincblendeTex[1];
  • trunk/packages/vizservers/nanovis/ZincBlendeVolume.h

    r3613 r3630  
    2121{
    2222public:
    23     ZincBlendeVolume(float x, float y, float z,
    24                      int width, int height, int depth, int numComponents,
     23    ZincBlendeVolume(int width, int height, int depth, int numComponents,
    2524                     float *dataVolumeA, float *dataVolumeB,
    26                      double vmin, double vmax, double non_zeromin, const vrmath::Vector3f& cellSize);
     25                     double vmin, double vmax, double non_zeromin,
     26                     const vrmath::Vector3f& cellSize);
    2727
    2828    virtual ~ZincBlendeVolume();
  • trunk/packages/vizservers/nanovis/ZincBlendeVolumeShader.cpp

    r3612 r3630  
    2121void ZincBlendeVolumeShader::init()
    2222{
    23     loadFragmentProgram("zincblende_volume.cg", "main");
     23    loadFragmentProgram("zincblende_volume.cg");
    2424}
    2525
  • trunk/packages/vizservers/nanovis/dxReader.cpp

    r3611 r3630  
    488488    delete [] data;
    489489
    490     //
    491     // Center this new volume on the origin.
    492     //
    493     float dx0 = -0.5;
    494     float dy0 = -0.5*ly/lx;
    495     float dz0 = -0.5*lz/lx;
    496     if (volume) {
    497         volume->location(vrmath::Vector3f(dx0, dy0, dz0));
    498         TRACE("Set volume location to %g %g %g", dx0, dy0, dz0);
    499     }
    500490    return volume;
    501491}
  • trunk/packages/vizservers/nanovis/graphics/Makefile.in

    r3470 r3630  
    5959
    6060clean:
    61         $(RM) $(NVGRAPHICSLIB) $(OBJS)
     61        $(RM) *.a *.o
    6262
    6363distclean: clean
  • trunk/packages/vizservers/nanovis/imgLoaders/Makefile.in

    r3470 r3630  
    5959
    6060clean:
    61         $(RM) $(IMGLIB) $(OBJS)
     61        $(RM) *.a *.o
    6262
    6363distclean: clean
  • trunk/packages/vizservers/nanovis/nanovis.cpp

    r3612 r3630  
    2424
    2525#include <graphics/RenderContext.h>
     26#include <vrmath/BBox.h>
    2627#include <vrmath/Vector3f.h>
    2728
     
    6465Tcl_Interp *NanoVis::interp = NULL;
    6566
    66 unsigned int NanoVis::flags = 0;
     67bool NanoVis::redrawPending = false;
    6768bool NanoVis::debugFlag = false;
    6869
     
    7374Texture2D *NanoVis::legendTexture = NULL;
    7475Fonts *NanoVis::fonts;
    75 int NanoVis::updir = Y_POS;
    76 Camera *NanoVis::cam = NULL;
     76Camera *NanoVis::_camera = NULL;
    7777RenderContext *NanoVis::renderContext = NULL;
    7878
     
    8282NanoVis::HeightMapHashmap NanoVis::heightMapTable;
    8383
    84 double NanoVis::magMin = DBL_MAX;
    85 double NanoVis::magMax = -DBL_MAX;
    86 float NanoVis::xMin = FLT_MAX;
    87 float NanoVis::xMax = -FLT_MAX;
    88 float NanoVis::yMin = FLT_MAX;
    89 float NanoVis::yMax = -FLT_MAX;
    90 float NanoVis::zMin = FLT_MAX;
    91 float NanoVis::zMax = -FLT_MAX;
    92 float NanoVis::wMin = FLT_MAX;
    93 float NanoVis::wMax = -FLT_MAX;
    94 Vector3f NanoVis::sceneMin, NanoVis::sceneMax;
     84BBox NanoVis::sceneBounds;
    9585
    9686VolumeRenderer *NanoVis::volRenderer = NULL;
     
    10191Grid *NanoVis::grid = NULL;
    10292
    103 // Image based flow visualization slice location
    104 // FLOW
    105 float NanoVis::_licSlice = 0.5f;
    106 int NanoVis::_licAxis = 2; // z axis
    107 
    10893//frame buffer for final rendering
    10994GLuint NanoVis::_finalFbo = 0;
     
    11196GLuint NanoVis::_finalDepthRb = 0;
    11297
    113 // Default camera location.
    114 float def_eye_x = 0.0f;
    115 float def_eye_y = 0.0f;
    116 float def_eye_z = 2.5f;
    117 
    11898void
    11999NanoVis::removeAllData()
    120100{
    121101    TRACE("Enter");
     102
    122103    if (grid != NULL) {
    123104        TRACE("Deleting grid");
    124105        delete grid;
    125106    }
    126     if (cam != NULL) {
    127         TRACE("Deleting cam");
    128         delete cam;
     107    if (_camera != NULL) {
     108        TRACE("Deleting camera");
     109        delete _camera;
    129110    }
    130111    if (volRenderer != NULL) {
     
    167148
    168149void
    169 NanoVis::eventuallyRedraw(unsigned int flag)
    170 {
    171     if (flag) {
    172         flags |= flag;
    173     }
    174     if ((flags & REDRAW_PENDING) == 0) {
     150NanoVis::eventuallyRedraw()
     151{
     152    if (!redrawPending) {
    175153        glutPostRedisplay();
    176         flags |= REDRAW_PENDING;
    177     }
    178 }
    179 
    180 void
    181 NanoVis::pan(float dx, float dy)
    182 {
    183     /* Move the camera and its target by equal amounts along the x and y
    184      * axes. */
    185     TRACE("pan: x=%f, y=%f", dx, dy);
    186 
    187     cam->x(def_eye_x - dx);
    188     cam->y(def_eye_y + dy);
    189     TRACE("set eye to %f %f", cam->x(), cam->y());
    190 }
    191 
    192 void
    193 NanoVis::zoom(float z)
    194 {
    195     /* Move the camera and its target by equal amounts along the x and y
    196      * axes. */
    197     TRACE("zoom: z=%f", z);
    198 
    199     cam->z(def_eye_z / z);
     154        redrawPending = true;
     155    }
     156}
     157
     158void
     159NanoVis::panCamera(float dx, float dy)
     160{
     161    _camera->pan(dx, dy);
    200162
    201163    collectBounds();
    202     cam->resetClippingRange(sceneMin, sceneMax);
    203 
    204     TRACE("set cam z to %f", cam->z());
     164    _camera->resetClippingRange(sceneBounds.min, sceneBounds.max);
     165}
     166
     167void
     168NanoVis::zoomCamera(float z)
     169{
     170    _camera->zoom(z);
     171
     172    collectBounds();
     173    _camera->resetClippingRange(sceneBounds.min, sceneBounds.max);
     174}
     175
     176void
     177NanoVis::orientCamera(double *quat)
     178{
     179    _camera->orient(quat);
     180
     181    collectBounds();
     182    _camera->resetClippingRange(sceneBounds.min, sceneBounds.max);
     183}
     184
     185void
     186NanoVis::setCameraPosition(Vector3f pos)
     187{
     188    _camera->setPosition(pos);
     189
     190    collectBounds();
     191    _camera->resetClippingRange(sceneBounds.min, sceneBounds.max);
     192}
     193
     194void
     195NanoVis::setCameraUpdir(Camera::AxisDirection dir)
     196{
     197    _camera->setUpdir(dir);
     198
     199    collectBounds();
     200    _camera->resetClippingRange(sceneBounds.min, sceneBounds.max);
    205201}
    206202
     
    211207
    212208    collectBounds();
    213     cam->reset(sceneMin, sceneMax, resetOrientation);
    214 
    215     def_eye_x = cam->x();
    216     def_eye_y = cam->y();
    217     def_eye_z = cam->z();
     209    _camera->reset(sceneBounds.min, sceneBounds.max, resetOrientation);
    218210}
    219211
     
    244236    }
    245237
    246     Volume *volume = new Volume(0.f, 0.f, 0.f,
    247                                 width, height, depth,
     238    Volume *volume = new Volume(width, height, depth,
    248239                                numComponents,
    249240                                data, vmin, vmax, nonZeroMin);
     
    451442    TRACE("change camera");
    452443    //change the camera setting
    453     cam->setScreenSize(0, 0, winWidth, winHeight);
     444    _camera->setViewport(0, 0, winWidth, winHeight);
    454445    planeRenderer->setScreenSize(winWidth, winHeight);
    455446
    456447    TRACE("Leave (%d, %d)", w, h);
    457448    return true;
    458 }
    459 
    460 static
    461 void cgErrorCallback(void)
    462 {
    463     if (!Shader::printErrorInfo()) {
    464         TRACE("Cg error, exiting...");
    465         exit(1);
    466     }
    467449}
    468450
     
    536518    ImageLoaderFactory::getInstance()->addLoaderImpl("bmp", new BMPImageLoaderImpl());
    537519
    538     Shader::initCg();
    539     Shader::setErrorCallback(cgErrorCallback);
    540 
    541     fonts = new Fonts();
    542     fonts->addFont("verdana", "verdana.fnt");
    543     fonts->setFont("verdana");
    544 
    545     velocityArrowsSlice = new VelocityArrowsSlice;
    546     licRenderer = new LIC(NMESH, NPIX, NPIX, _licAxis, _licSlice);
    547 
    548     grid = new Grid();
    549     grid->setFont(fonts);
    550520    return true;
    551521}
     
    564534
    565535    //create the camera with default setting
    566     cam = new Camera(0, 0, winWidth, winHeight,
    567                      def_eye_x, def_eye_y, def_eye_z);
     536    _camera = new Camera(0, 0, winWidth, winHeight);
    568537
    569538    glEnable(GL_TEXTURE_2D);
     
    577546    GLfloat mat_shininess[] = {30.0};
    578547    GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
    579     GLfloat green_light[] = {0.1, 0.5, 0.1, 1.0};
    580548
    581549    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
     
    583551    glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
    584552    glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
    585     glLightfv(GL_LIGHT1, GL_DIFFUSE, green_light);
     553    glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light);
    586554    glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
    587555
     
    591559    }
    592560
     561    fonts = new Fonts();
     562    fonts->addFont("verdana", "verdana.fnt");
     563    fonts->setFont("verdana");
     564
     565    renderContext = new RenderContext();
     566
    593567    volRenderer = new VolumeRenderer();
    594568
    595     renderContext = new RenderContext();
    596 
    597569    planeRenderer = new PlaneRenderer(winWidth, winHeight);
    598570
     571    velocityArrowsSlice = new VelocityArrowsSlice();
     572
     573    licRenderer = new LIC();
     574
    599575    orientationIndicator = new OrientationIndicator();
     576
     577    grid = new Grid();
     578    grid->setFont(fonts);
    600579
    601580    //assert(glGetError()==0);
     
    635614NanoVis::setVolumeRanges()
    636615{
    637     double xMin, xMax, yMin, yMax, zMin, zMax, wMin, wMax;
    638 
    639616    TRACE("Enter");
    640     xMin = yMin = zMin = wMin = DBL_MAX;
    641     xMax = yMax = zMax = wMax = -DBL_MAX;
     617
     618    double valueMin = DBL_MAX, valueMax = -DBL_MAX;
    642619    VolumeHashmap::iterator itr;
    643620    for (itr = volumeTable.begin();
    644621         itr != volumeTable.end(); ++itr) {
    645622        Volume *volume = itr->second;
    646         if (xMin > volume->xAxis.min()) {
    647             xMin = volume->xAxis.min();
    648         }
    649         if (xMax < volume->xAxis.max()) {
    650             xMax = volume->xAxis.max();
    651         }
    652         if (yMin > volume->yAxis.min()) {
    653             yMin = volume->yAxis.min();
    654         }
    655         if (yMax < volume->yAxis.max()) {
    656             yMax = volume->yAxis.max();
    657         }
    658         if (zMin > volume->zAxis.min()) {
    659             zMin = volume->zAxis.min();
    660         }
    661         if (zMax < volume->zAxis.max()) {
    662             zMax = volume->zAxis.max();
    663         }
    664         if (wMin > volume->wAxis.min()) {
    665             wMin = volume->wAxis.min();
    666         }
    667         if (wMax < volume->wAxis.max()) {
    668             wMax = volume->wAxis.max();
    669         }
    670     }
    671     if ((xMin < DBL_MAX) && (xMax > -DBL_MAX)) {
    672         grid->xAxis.setScale(xMin, xMax);
    673     }
    674     if ((yMin < DBL_MAX) && (yMax > -DBL_MAX)) {
    675         grid->yAxis.setScale(yMin, yMax);
    676     }
    677     if ((zMin < DBL_MAX) && (zMax > -DBL_MAX)) {
    678         grid->zAxis.setScale(zMin, zMax);
    679     }
    680     if ((wMin < DBL_MAX) && (wMax > -DBL_MAX)) {
    681         Volume::valueMin = wMin;
    682         Volume::valueMax = wMax;
     623        if (valueMin > volume->wAxis.min()) {
     624            valueMin = volume->wAxis.min();
     625        }
     626        if (valueMax < volume->wAxis.max()) {
     627            valueMax = volume->wAxis.max();
     628        }
     629    }
     630    if ((valueMin < DBL_MAX) && (valueMax > -DBL_MAX)) {
     631        Volume::valueMin = valueMin;
     632        Volume::valueMax = valueMax;
    683633    }
    684634    Volume::updatePending = false;
     
    689639NanoVis::setHeightmapRanges()
    690640{
    691     double xMin, xMax, yMin, yMax, zMin, zMax, wMin, wMax;
    692 
    693641    TRACE("Enter");
    694     xMin = yMin = zMin = wMin = DBL_MAX;
    695     xMax = yMax = zMax = wMax = -DBL_MAX;
     642
     643    double valueMin = DBL_MAX, valueMax = -DBL_MAX;
    696644    HeightMapHashmap::iterator itr;
    697645    for (itr = heightMapTable.begin();
    698646         itr != heightMapTable.end(); ++itr) {
    699647        HeightMap *heightMap = itr->second;
    700         if (xMin > heightMap->xAxis.min()) {
    701             xMin = heightMap->xAxis.min();
    702         }
    703         if (xMax < heightMap->xAxis.max()) {
    704             xMax = heightMap->xAxis.max();
    705         }
    706         if (yMin > heightMap->yAxis.min()) {
    707             yMin = heightMap->yAxis.min();
    708         }
    709         if (yMax < heightMap->yAxis.max()) {
    710             yMax = heightMap->yAxis.max();
    711         }
    712         if (zMin > heightMap->zAxis.min()) {
    713             zMin = heightMap->zAxis.min();
    714         }
    715         if (zMax < heightMap->zAxis.max()) {
    716             zMax = heightMap->zAxis.max();
    717         }
    718         if (wMin > heightMap->wAxis.min()) {
    719             wMin = heightMap->wAxis.min();
    720         }
    721         if (wMax < heightMap->wAxis.max()) {
    722             wMax = heightMap->wAxis.max();
    723         }
    724     }
    725     if ((xMin < DBL_MAX) && (xMax > -DBL_MAX)) {
    726         grid->xAxis.setScale(xMin, xMax);
    727     }
    728     if ((yMin < DBL_MAX) && (yMax > -DBL_MAX)) {
    729         grid->yAxis.setScale(yMin, yMax);
    730     }
    731     if ((zMin < DBL_MAX) && (zMax > -DBL_MAX)) {
    732         grid->zAxis.setScale(zMin, zMax);
    733     }
    734     if ((wMin < DBL_MAX) && (wMax > -DBL_MAX)) {
    735         HeightMap::valueMin = grid->yAxis.min();
    736         HeightMap::valueMax = grid->yAxis.max();
     648        if (valueMin > heightMap->wAxis.min()) {
     649            valueMin = heightMap->wAxis.min();
     650        }
     651        if (valueMax < heightMap->wAxis.max()) {
     652            valueMax = heightMap->wAxis.max();
     653        }
     654    }
     655    if ((valueMin < DBL_MAX) && (valueMax > -DBL_MAX)) {
     656        HeightMap::valueMin = valueMin;
     657        HeightMap::valueMax = valueMax;
    737658    }
    738659    for (HeightMapHashmap::iterator itr = heightMapTable.begin();
     
    747668NanoVis::collectBounds(bool onlyVisible)
    748669{
    749     if (flags & MAP_FLOWS) {
     670    if (Flow::updatePending) {
    750671        mapFlows();
    751         grid->xAxis.setScale(xMin, xMax);
    752         grid->yAxis.setScale(yMin, yMax);
    753         grid->zAxis.setScale(zMin, zMax);
    754     }
    755 
    756     sceneMin.set(FLT_MAX, FLT_MAX, FLT_MAX);
    757     sceneMax.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
     672    }
     673
     674    sceneBounds.makeEmpty();
    758675
    759676    for (VolumeHashmap::iterator itr = volumeTable.begin();
     
    764681            continue;
    765682
    766         Vector3f bmin, bmax;
    767         volume->getWorldSpaceBounds(bmin, bmax);
    768         if (bmin.x > bmax.x)
    769             continue;
    770 
    771         if (sceneMin.x > bmin.x) {
    772             sceneMin.x = bmin.x;
    773         }
    774         if (sceneMax.x < bmax.x) {
    775             sceneMax.x = bmax.x;
    776         }
    777         if (sceneMin.y > bmin.y) {
    778             sceneMin.y = bmin.y;
    779         }
    780         if (sceneMax.y < bmax.y) {
    781             sceneMax.y = bmax.y;
    782         }
    783         if (sceneMin.z > bmin.z) {
    784             sceneMin.z = bmin.z;
    785         }
    786         if (sceneMax.z < bmax.z) {
    787             sceneMax.z = bmax.z;
    788         }
     683        BBox bbox;
     684        volume->getBounds(bbox.min, bbox.max);
     685        sceneBounds.extend(bbox);
    789686    }
    790687
     
    796693            continue;
    797694
    798         Vector3f bmin, bmax;
    799         heightMap->getWorldSpaceBounds(bmin, bmax);
    800         if (bmin.x > bmax.x)
    801             continue;
    802 
    803         if (sceneMin.x > bmin.x) {
    804             sceneMin.x = bmin.x;
    805         }
    806         if (sceneMax.x < bmax.x) {
    807             sceneMax.x = bmax.x;
    808         }
    809         if (sceneMin.y > bmin.y) {
    810             sceneMin.y = bmin.y;
    811         }
    812         if (sceneMax.y < bmax.y) {
    813             sceneMax.y = bmax.y;
    814         }
    815         if (sceneMin.z > bmin.z) {
    816             sceneMin.z = bmin.z;
    817         }
    818         if (sceneMax.z < bmax.z) {
    819             sceneMax.z = bmax.z;
    820         }
    821     }
    822 
    823     Vector3f flowMin, flowMax;
    824     getFlowBounds(flowMin, flowMax, onlyVisible);
    825     if (flowMin.x < flowMax.x) {
    826         if (sceneMin.x > flowMin.x) {
    827             sceneMin.x = flowMin.x;
    828         }
    829         if (sceneMax.x < flowMax.x) {
    830             sceneMax.x = flowMax.x;
    831         }
    832         if (sceneMin.y > flowMin.y) {
    833             sceneMin.y = flowMin.y;
    834         }
    835         if (sceneMax.y < flowMax.y) {
    836             sceneMax.y = flowMax.y;
    837         }
    838         if (sceneMin.z > flowMin.z) {
    839             sceneMin.z = flowMin.z;
    840         }
    841         if (sceneMax.z < flowMax.z) {
    842             sceneMax.z = flowMax.z;
    843         }
    844     }
    845 
    846     // TODO: Get Grid bounds
    847 
    848     if (sceneMin.x > sceneMax.x) {
    849         sceneMin.set(-0.5, -0.5, -0.5);
    850         sceneMax.set( 0.5,  0.5,  0.5);
     695        BBox bbox;
     696        heightMap->getBounds(bbox.min, bbox.max);
     697        sceneBounds.extend(bbox);
     698    }
     699
     700    {
     701        BBox bbox;
     702        getFlowBounds(bbox.min, bbox.max, onlyVisible);
     703        sceneBounds.extend(bbox);
     704    }
     705
     706    if (!sceneBounds.isEmptyX()) {
     707        grid->xAxis.setScale(sceneBounds.min.x, sceneBounds.max.x);
     708    }
     709    if (!sceneBounds.isEmptyY()) {
     710        grid->yAxis.setScale(sceneBounds.min.y, sceneBounds.max.y);
     711    }
     712    if (!sceneBounds.isEmptyZ()) {
     713        grid->zAxis.setScale(sceneBounds.min.z, sceneBounds.max.z);
     714    }
     715
     716    if (!onlyVisible || grid->isVisible()) {
     717        BBox bbox;
     718        grid->getBounds(bbox.min, bbox.max);
     719        sceneBounds.extend(bbox);
     720    }
     721
     722    if (sceneBounds.isEmpty()) {
     723        sceneBounds.min.set(-0.5, -0.5, -0.5);
     724        sceneBounds.max.set( 0.5,  0.5,  0.5);
    851725    }
    852726
    853727    TRACE("Scene bounds: (%g,%g,%g) - (%g,%g,%g)",
    854           sceneMin.x, sceneMin.y, sceneMin.z,
    855           sceneMax.x, sceneMax.y, sceneMax.z);
     728          sceneBounds.min.x, sceneBounds.min.y, sceneBounds.min.z,
     729          sceneBounds.max.x, sceneBounds.max.y, sceneBounds.max.z);
    856730}
    857731
     
    933807    TRACE("Enter");
    934808
    935     flags &= ~MAP_FLOWS;
    936 
    937809    /*
    938810     * Step 1. Get the overall min and max magnitudes of all the
    939811     *         flow vectors.
    940812     */
    941     magMin = DBL_MAX, magMax = -DBL_MAX;
     813    Flow::magMin = DBL_MAX;
     814    Flow::magMax = -DBL_MAX;
    942815
    943816    for (FlowHashmap::iterator itr = flowTable.begin();
     
    951824        min = data->magMin();
    952825        max = data->magMax();
    953         if (min < magMin) {
    954             magMin = min;
     826        if (min < Flow::magMin) {
     827            Flow::magMin = min;
    955828        }
    956         if (max > magMax) {
    957             magMax = max;
    958         }
    959         if (data->xMin() < xMin) {
    960             xMin = data->xMin();
    961         }
    962         if (data->yMin() < yMin) {
    963             yMin = data->yMin();
    964         }
    965         if (data->zMin() < zMin) {
    966             zMin = data->zMin();
    967         }
    968         if (data->xMax() > xMax) {
    969             xMax = data->xMax();
    970         }
    971         if (data->yMax() > yMax) {
    972             yMax = data->yMax();
    973         }
    974         if (data->zMax() > zMax) {
    975             zMax = data->zMax();
    976         }
    977     }
    978 
    979     TRACE("magMin=%g magMax=%g", NanoVis::magMin, NanoVis::magMax);
     829        if (max > Flow::magMax) {
     830            Flow::magMax = max;
     831        }
     832    }
     833
     834    TRACE("magMin=%g magMax=%g", Flow::magMin, Flow::magMax);
    980835
    981836    /*
     
    994849            return false;
    995850        }
    996         // FIXME: This doesn't work when there is more than one flow.
    997         licRenderer->setOffset(flow->getRelativePosition());
    998         velocityArrowsSlice->slicePos(flow->getRelativePosition());
    999     }
    1000     advectFlows();
     851    }
     852
     853    Flow::updatePending = false;
    1001854    return true;
    1002855}
     
    1009862    TRACE("Enter");
    1010863
    1011     min.set(FLT_MAX, FLT_MAX, FLT_MAX);
    1012     max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    1013 
     864    BBox allBounds;
    1014865    for (FlowHashmap::iterator itr = flowTable.begin();
    1015866         itr != flowTable.end(); ++itr) {
    1016         itr->second->getBounds(min, max, onlyVisible);
    1017     }
     867        BBox bbox;
     868        itr->second->getBounds(bbox.min, bbox.max, onlyVisible);
     869        allBounds.extend(bbox);
     870    }
     871
     872    min = allBounds.min;
     873    max = allBounds.max;
    1018874}
    1019875
     
    1028884        }
    1029885    }
    1030     flags &= ~REDRAW_PENDING;
    1031886}
    1032887
     
    1034889NanoVis::resetFlows()
    1035890{
    1036     if (licRenderer->active()) {
    1037         NanoVis::licRenderer->reset();
    1038     }
     891    NanoVis::licRenderer->reset();
    1039892    for (FlowHashmap::iterator itr = flowTable.begin();
    1040893         itr != flowTable.end(); ++itr) {
    1041894        Flow *flow = itr->second;
    1042         if (flow->isDataLoaded() && flow->visible()) {
     895        if (flow->isDataLoaded()) {
    1043896            flow->resetParticles();
    1044897        }
     
    1049902NanoVis::advectFlows()
    1050903{
     904    TRACE("Enter");
    1051905    for (FlowHashmap::iterator itr = flowTable.begin();
    1052906         itr != flowTable.end(); ++itr) {
    1053907        Flow *flow = itr->second;
    1054         if (flow->isDataLoaded() && flow->visible()) {
     908        if (flow->isDataLoaded()) {
    1055909            flow->advect();
    1056910        }
     
    1063917    TRACE("Enter");
    1064918
    1065     if (flags & MAP_FLOWS) {
    1066 #ifdef notdef
    1067         xMin = yMin = zMin = wMin = FLT_MAX, magMin = DBL_MAX;
    1068         xMax = yMax = zMax = wMax = -FLT_MAX, magMax = -DBL_MAX;
    1069 #endif
     919    if (Flow::updatePending) {
    1070920        mapFlows();
    1071         grid->xAxis.setScale(xMin, xMax);
    1072         grid->yAxis.setScale(yMin, yMax);
    1073         grid->zAxis.setScale(zMin, zMax);
    1074     }
    1075     //assert(glGetError()==0);
     921    }
    1076922    if (HeightMap::updatePending) {
    1077923        setHeightmapRanges();
     
    1081927    }
    1082928
    1083     //start final rendering
     929    collectBounds();
     930
     931    // Start final rendering
    1084932
    1085933    // Need to reset fbo since it may have been changed to default (0)
     
    1092940    glEnable(GL_COLOR_MATERIAL);
    1093941
    1094     //camera setting activated
    1095     cam->initialize();
    1096 
    1097     //set up the orientation of items in the scene.
    1098     glPushMatrix();
    1099 
    1100     switch (updir) {
    1101     case X_POS:
    1102         glRotatef(90, 0, 0, 1);
    1103         glRotatef(90, 1, 0, 0);
    1104         break;
    1105     case Y_POS:
    1106         // this is the default
    1107         break;
    1108     case Z_POS:
    1109         glRotatef(-90, 1, 0, 0);
    1110         glRotatef(-90, 0, 0, 1);
    1111         break;
    1112     case X_NEG:
    1113         glRotatef(-90, 0, 0, 1);
    1114         break;
    1115     case Y_NEG:
    1116         glRotatef(180, 0, 0, 1);
    1117         glRotatef(-90, 0, 1, 0);
    1118         break;
    1119     case Z_NEG:
    1120         glRotatef(90, 1, 0, 0);
    1121         break;
    1122     }
    1123 
    1124     //now render things in the scene
    1125 
     942    // Emit modelview and projection matrices
     943    _camera->initialize();
     944
     945    // Now render things in the scene
     946
     947    orientationIndicator->setPosition(sceneBounds.getCenter());
     948    orientationIndicator->setScale(sceneBounds.getSize());
    1126949    orientationIndicator->render();
     950
    1127951    grid->render();
    1128     if ((licRenderer != NULL) && (licRenderer->active())) {
    1129         licRenderer->render();
    1130     }
    1131     if ((velocityArrowsSlice != NULL) && (velocityArrowsSlice->enabled())) {
    1132         velocityArrowsSlice->render();
    1133     }
     952
     953    licRenderer->render();
     954
     955    velocityArrowsSlice->render();
     956
    1134957    renderFlows();
     958
    1135959    volRenderer->renderAll();
    1136960
    1137     HeightMapHashmap::iterator itr;
    1138     for (itr = heightMapTable.begin();
     961    for (HeightMapHashmap::iterator itr = heightMapTable.begin();
    1139962         itr != heightMapTable.end(); ++itr) {
    1140         HeightMap *heightMap = itr->second;
    1141         if (heightMap->isVisible()) {
    1142             heightMap->render(renderContext);
    1143         }
    1144     }
    1145     glPopMatrix();
     963        itr->second->render(renderContext);
     964     }
    1146965
    1147966    CHECK_FRAMEBUFFER_STATUS();
    1148967    TRACE("Leave");
    1149 }
     968    redrawPending = false;
     969}
  • trunk/packages/vizservers/nanovis/nanovis.h

    r3626 r3630  
    3131#include <tr1/unordered_map>
    3232
     33#include <vrmath/BBox.h>
    3334#include <vrmath/Vector3f.h>
    3435
    3536#include "config.h"
     37#include "Camera.h"
     38#include "FlowTypes.h"
    3639#include "md5.h"
    3740
     
    4851}
    4952
    50 class Camera;
    5153class Flow;
    5254class Grid;
     
    6466{
    6567public:
    66     enum AxisDirections {
    67         X_POS = 1,
    68         Y_POS = 2,
    69         Z_POS = 3,
    70         X_NEG = -1,
    71         Y_NEG = -2,
    72         Z_NEG = -3
    73     };
    74 
    75     enum NanoVisFlags {
    76         REDRAW_PENDING = (1 << 0),
    77         MAP_FLOWS = (1 << 1)
    78     };
    79 
    8068    typedef std::string TransferFunctionId;
    8169    typedef std::string VolumeId;
     
    9886    static const Camera *getCamera()
    9987    {
    100         return cam;
     88        return _camera;
    10189    }
    102     static void pan(float dx, float dy);
    103     static void zoom(float z);
     90    static void panCamera(float dx, float dy);
     91    static void zoomCamera(float z);
     92    static void orientCamera(double *quat);
     93    static void setCameraPosition(vrmath::Vector3f pos);
     94    static void setCameraUpdir(Camera::AxisDirection dir);
    10495    static void resetCamera(bool resetOrientation = false);
    10596
    106     static void eventuallyRedraw(unsigned int flag = 0);
    107 
    108     static void setVolumeRanges();
    109     static void setHeightmapRanges();
     97    static void eventuallyRedraw();
    11098 
    11199    static TransferFunction *getTransferFunction(const TransferFunctionId& id);
     
    133121    }
    134122
     123    static void setVolumeRanges();
     124    static void setHeightmapRanges();
     125    static bool mapFlows();
     126
    135127    static Flow *getFlow(const char *name);
    136128    static Flow *createFlow(Tcl_Interp *interp, const char *name);
    137129    static void deleteFlows(Tcl_Interp *interp);
    138130    static void deleteFlow(const char *name);
    139     static bool mapFlows();
    140131    static void getFlowBounds(vrmath::Vector3f& min,
    141132                              vrmath::Vector3f& max,
     
    148139    static Tcl_Interp *interp;
    149140
    150     static unsigned int flags;
     141    static bool redrawPending;
    151142    static bool debugFlag;
    152143
    153144    static int winWidth;        ///< Width of the render window
    154145    static int winHeight;       ///< Height of the render window
    155     static int renderWindow;    //< GLUT handle for the render window
     146    static int renderWindow;    ///< GLUT handle for the render window
    156147    static unsigned char *screenBuffer;
    157148    static Texture2D *legendTexture;
    158149    static util::Fonts *fonts;
    159     static int updir;
    160     static Camera *cam;
    161150    static graphics::RenderContext *renderContext;
    162151
     
    166155    static HeightMapHashmap heightMapTable;
    167156
    168     static double magMin, magMax;
    169     static float xMin, xMax, yMin, yMax, zMin, zMax, wMin, wMax;
    170     static vrmath::Vector3f sceneMin, sceneMax;
     157    static vrmath::BBox sceneBounds;
    171158
    172159    static VolumeRenderer *volRenderer;
     
    180167    static void collectBounds(bool onlyVisible = false);
    181168
    182     static float _licSlice;  ///< Slice position [0,1]
    183     static int _licAxis;     ///< Slice axis: 0:x, 1:y, 2:z
     169    static Camera *_camera;
    184170
    185171    //frame buffer for final rendering
  • trunk/packages/vizservers/nanovis/nanovisServer.cpp

    r3614 r3630  
    352352    NanoVis::removeAllData();
    353353
    354     Shader::exitCg();
     354    Shader::exit();
    355355
    356356    //close log file
     
    434434
    435435static
    436 void cgErrorCallback(void)
     436void shaderErrorCallback(void)
    437437{
    438438    if (!Shader::printErrorInfo()) {
    439         TRACE("Cg error, exiting...");
     439        TRACE("Shader error, exiting...");
    440440        exitService(1);
    441441    }
     
    579579    }
    580580
     581    Shader::init();
    581582    // Override callback with one that cleans up server on exit
    582     Shader::setErrorCallback(cgErrorCallback);
     583    Shader::setErrorCallback(shaderErrorCallback);
    583584
    584585    if (!NanoVis::initGL()) {
  • trunk/packages/vizservers/nanovis/newmat11/Makefile.in

    r3470 r3630  
    7373
    7474clean:
    75         $(RM) $(MATLIB) $(OBJS)
     75        $(RM) *.a *.o
    7676