source: nanovis/trunk/VolumeInterpolator.cpp @ 4897

Last change on this file since 4897 was 3630, checked in by ldelgass, 7 years ago

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.

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