source: nanovis/branches/1.1/VolumeInterpolator.cpp @ 5722

Last change on this file since 5722 was 4908, checked in by ldelgass, 9 years ago

Merge r4907 from trunk

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