source: trunk/packages/vizservers/nanovis/VolumeInterpolator.cpp @ 3492

Last change on this file since 3492 was 3492, checked in by ldelgass, 6 years ago

Fix camera reset for nanovis. Includes refactoring of vector/matrix classes
in nanovis to consolidate into vrmath library. Also add preliminary canonical
view control to clients for testing.

  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#include <string.h>
3#include <memory.h>
4#include <time.h>
5#include <sys/time.h>
6#include <math.h>
7#include <stdlib.h>
8
9#include <vrmath/Vector3f.h>
10
11#include "VolumeInterpolator.h"
12#include "Volume.h"
13#include "Trace.h"
14
15using namespace vrmath;
16
17VolumeInterpolator::VolumeInterpolator() : 
18    _volume(0), 
19    _interval(8.0), 
20    _started(false), 
21    _numBytes(0), 
22    _dataCount(0), 
23    _numComponents(0)
24{
25}
26
27void VolumeInterpolator::start()
28{
29    if (_volumes.size() > 0) {
30        TRACE("Volume Interpolation Started");
31        _started = true;
32    } else {
33        TRACE("Volume Interpolation NOT Started");
34        _started = false;
35    }
36    struct timeval clock;
37    gettimeofday(&clock, NULL);
38    _startTime = clock.tv_sec + clock.tv_usec/1000000.0;
39    TRACE("Leave");
40}
41
42void VolumeInterpolator::stop()
43{
44    _started = false;
45}
46
47Volume *VolumeInterpolator::update(float fraction)
48{
49    int key1, key2;
50    float interp;
51
52    computeKeys(fraction, _volumes.size(), &interp, &key1, &key2);
53
54    if (interp == 0.0f) {
55        memcpy(_volume->data(), _volumes[key1]->data(), _numBytes);
56        _volume->tex()->update(_volume->data());
57    } else {
58        float *data1 = _volumes[key1]->data();
59        float *data2 = _volumes[key2]->data();
60        float *result = _volume->data();
61
62        Vector3f normal1, normal2, normal;
63        for (unsigned int i = 0; i < _dataCount; ++i) {
64            *result = interp * (*data2 - *data1) + *data1;
65            normal1 = (*(Vector3f*)(data1 + 1) - 0.5) * 2;
66            normal2 = (*(Vector3f*)(data2 + 1) - 0.5) * 2;
67            normal = (normal2 - normal2) * interp + normal1;
68            normal = normal.normalize();
69            normal = normal * 0.5 + 0.5;
70            *((Vector3f*)(result + 1)) = normal;
71
72            result += _numComponents;
73            data1 += _numComponents;
74            data2 += _numComponents;
75        }
76
77        _volume->tex()->update(_volume->data());
78    }
79
80    return _volume;
81}
82
83void
84VolumeInterpolator::computeKeys(float fraction, int count, float *interp, 
85                                int *key1, int *key2)
86{
87    int limit = (int) count - 1;
88    if (fraction <= 0) {
89        *key1 = *key2 = 0;
90        *interp = 0.0f;
91    } else if (fraction >= 1.0f) {
92        *key1 = *key2 = limit;
93        *interp = 0.0f;
94    } else {
95        int n;
96        for (n = 0; n < limit; n++){
97            if (fraction >= (n / (count - 1.0f)) && 
98                fraction < ((n+1)/(count-1.0f))) {
99                break;
100            }
101        }
102
103        TRACE("n = %d count = %d", n, count);
104        if (n >= limit) {
105            *key1 = *key2 = limit;
106            *interp = 0.0f;
107        } else {
108            *key1 = n;
109            *key2 = n+1;
110            *interp = (fraction - (n / (count -1.0f))) / ((n + 1) / (count - 1.0f) - n / (count - 1.0f));
111            //*ret = inter * (keyValue[n + 1] - keyValue[n]) + keyValue[n];
112        }
113    }
114}
115
116void
117VolumeInterpolator::clearAll()
118{
119    _volumes.clear();
120}
121
122void
123VolumeInterpolator::addVolume(Volume *refPtr)
124{
125    if (_volumes.size() != 0) {
126        if (_volumes[0]->width() != refPtr->width() || 
127            _volumes[0]->height() != refPtr->height() ||   
128            _volumes[0]->depth() != refPtr->depth() || 
129            _volumes[0]->numComponents() != refPtr->numComponents()) {
130            TRACE("The volume should be the same width, height, number of components");
131            return;
132        }
133    } else {
134        _dataCount = refPtr->width() * refPtr->height() * refPtr->depth();
135        _numComponents = refPtr->numComponents();
136        _numBytes = _dataCount * _numComponents * sizeof(float);
137        Vector3f loc = refPtr->location();
138        _volume = new Volume(loc.x, loc.y, loc.z,
139                             refPtr->width(),
140                             refPtr->height(),
141                             refPtr->depth(), 
142                             refPtr->numComponents(), 
143                             refPtr->data(), 
144                             refPtr->wAxis.min(), 
145                             refPtr->wAxis.max(), 
146                             refPtr->nonZeroMin());
147
148        _volume->numSlices(256-1);
149        _volume->disableCutplane(0);
150        _volume->disableCutplane(1);
151        _volume->disableCutplane(2);
152        _volume->visible(true);
153        _volume->dataEnabled(true);
154        _volume->ambient(refPtr->ambient());
155        _volume->diffuse(refPtr->diffuse());
156        _volume->specularLevel(refPtr->specularLevel());
157        _volume->specularExponent(refPtr->specularExponent());
158        _volume->opacityScale(refPtr->opacityScale());
159        _volume->isosurface(0);
160        TRACE("VOL : location %f %f %f\n\tid : %s", loc.x, loc.y, loc.z, 
161               refPtr->name());
162    }
163    _volumes.push_back(_volume);
164    TRACE("a Volume[%s] is added to VolumeInterpolator", refPtr->name());
165}
166
167Volume *VolumeInterpolator::getVolume()
168{
169    return _volume;
170    //return _volumes[0];
171}
Note: See TracBrowser for help on using the repository browser.