【问题标题】:Using three.js with time series data将 three.js 与时间序列数据一起使用
【发布时间】:2014-05-10 02:02:02
【问题描述】:

如何最好地使用时间序列数据来指导 three.js 场景的动画?

例如:

  Time     | ObjA(x,y,z) | ObjB(x,y,z) | ...
  00:00:00 | 0,9,0       | 1,1,1       | ...
  00:00:10 | 0.1,0,0.1   | 1,0.5,1     | ...
  00:00:15 | 0.1,0.1,0.1 | 0.9,0.5,1   | ...

数据可能有数百行,甚至数千行。并且对象的数量也可以从数据集到数据集变化。

我已经阅读了有关使用 tween.js 和链接关键帧的内容。但是在初始化过程中创建和链接成千上万的补间并不是正确的答案。

tween.js 是正确的方法吗?还是我错过了可以更好地处理这种情况的延期?有什么类似的用例可以证明有用吗?

更新

所以Director.js 肯定能够给出正确的结果。但看起来它的目的是对场景周围的相机运动进行补间,而不是指导数百个网格的运动。在可能数百个网格上将可能数千个补间链接在一起是实现脚本重放的最佳方式吗?

【问题讨论】:

  • 先看看stackoverflow.com/questions/17563076/…。如果基于补间的方法不是您想要的,那么考虑为每个对象创建一个 3D 路径并在每个帧中调用函数 getPointAt( t )。例如,参见threejs.org/examples/webgl_geometry_extrude_splines.html 中的动画。
  • Director.js 脚本当然是一个选项,我已经使用它了。我根本不反对基于补间的方法,但它看起来就像循环遍历数据列表并链接潜在的数千个补间似乎效率低下。播放听起来像是一个例行公事,以至于我想知道我是否错过了一些非常明显的东西。感谢您提供指向 3D 路径的链接。我现在就去看看。
  • 也许可以试试 Greensock 的 TimelineLite。 greensock.com/sequence-video。文档:api.greensock.com/js

标签: javascript opengl-es three.js webgl


【解决方案1】:

您提供的表格有点误导。通常,如果您有一个时间线,并且对象的数量是动态的 - 您将创建多个时间线,每个时间线一个 - 这样可以更轻松地操作整个集合。

var Record = function(time, value){
    this.time = time;
    this.value = value;
};
var Signal = function(){
    this.records = [];
    this.findValue = function(time){
        //... some divide and conquer implementation
    }
    this.getInterpolatedValue = function(time){...};
    this.add = function(time,value){
        //make sure sequence is preserved by doing a check or just assuming that add is always called with time greater than what's already in the series
        this.records.push(new Record(time,value));
    }
};

var signalObjA = new Signal();
var signalObjB = new Signal();

当涉及到回放时,某种类型的插值是必要的,并且您可能需要某种类型的动画管理器,它需要(信号、对象)对并根据当前时间从信号中设置对象值。

var Binding = function(signal, object){
    this.signal = signal;
    this.object = object;
    this.applyTime = function(t){
       var val = this.signal.getInterpolatedValue(t);
       for(var p in val){
           if(val.hasOwnProperty(p)){
               this.object[p] = val[p]; //copying values into object
           }
       }
    }
}
var Simulator = function(){
    this.time = 0;
    this.bindings = [];
    this.step = function(timeDelta){
        this.time += timeDelta;
        var time = this.time;
        this.bindings.forEach(function(b){
            b.applyTime(time);
        });
    }
}

如果您遇到空间问题,请尝试将 Records 展平为 Float32Array 或您选择的其他二进制缓冲区。

编辑:

请注意,这种方法旨在节省内存并删除数据转换。一个节省堆使用和 GC,另一个节省 CPU 时间。

【讨论】:

  • 我很好奇为什么它被降级。有问题的人有时间序列数据,而不是可以由某种补间处理的单个转换。我认为使用补间是完全错误的做法。如果您要在屏幕上为视频绘制图片,您会使用 800*600 1pixel 帧缓冲区和每个缓冲区的计时器来驱动切换吗?
猜你喜欢
  • 2015-01-03
  • 2012-10-15
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 2018-05-25
  • 2016-12-20
相关资源
最近更新 更多