mirror of
https://github.com/MapMakersAndProgrammers/alternativa3d-archive.git
synced 2025-10-27 18:29:07 -07:00
71 lines
3.0 KiB
ActionScript
71 lines
3.0 KiB
ActionScript
package alternativa.engine3d.core {
|
||
import alternativa.engine3d.alternativa3d;
|
||
|
||
import flash.display.BitmapData;
|
||
import flash.filters.ConvolutionFilter;
|
||
import flash.geom.Matrix;
|
||
import flash.geom.Point;
|
||
import flash.geom.Rectangle;
|
||
|
||
use namespace alternativa3d;
|
||
|
||
/**
|
||
* Объект, представляющий текстуру в виде последовательности её уменьшенных копий.
|
||
* Каждая следующая в два раза меньше предыдущей. Последняя имеет размер 1х1 пиксел.
|
||
* Чем дальше от камеры отрисовываемый объект, тем меньшая текстура выбирается.
|
||
* Это позволяет получить лучший визуальный результат и большую производительность.
|
||
*/
|
||
public class MipMap {
|
||
|
||
/**
|
||
* Мип-текстуры
|
||
*/
|
||
public var textures:Vector.<BitmapData> = new Vector.<BitmapData>();
|
||
/**
|
||
* Количество мип-текстур
|
||
*/
|
||
public var num:int;
|
||
/**
|
||
* Отношение размера пиксела текстуры к единице измерения трёхмерного пространства
|
||
*/
|
||
public var resolution:Number;
|
||
|
||
static private const filter:ConvolutionFilter = new ConvolutionFilter(2, 2, [1, 1, 1, 1], 4, 0, false, true);
|
||
static private const point:Point = new Point();
|
||
static private const matrix:Matrix = new Matrix();
|
||
static private const rect:Rectangle = new Rectangle();
|
||
public function MipMap(texture:BitmapData, resolution:Number = 1) {
|
||
var bmp:BitmapData = new BitmapData(texture.width, texture.height, texture.transparent);
|
||
var current:BitmapData = textures[num++] = texture;
|
||
filter.preserveAlpha = !texture.transparent;
|
||
var w:Number = rect.width = texture.width, h:Number = rect.height = texture.height;
|
||
while (w > 1 && h > 1 && rect.width > 1 && rect.height > 1) {
|
||
bmp.applyFilter(current, rect, point, filter);
|
||
rect.width = w >> 1;
|
||
rect.height = h >> 1;
|
||
matrix.a = rect.width/w;
|
||
matrix.d = rect.height/h;
|
||
w *= 0.5;
|
||
h *= 0.5;
|
||
current = new BitmapData(rect.width, rect.height, texture.transparent, 0);
|
||
current.draw(bmp, matrix, null, null, null, false);
|
||
textures[num++] = current;
|
||
}
|
||
bmp.dispose();
|
||
this.resolution = resolution;
|
||
}
|
||
|
||
/**
|
||
* Получение мип-уровня в зависимости от удалённости объекта от камеры
|
||
* @param distance Z-координата объекта в пространстве камеры
|
||
* @param camera Камера
|
||
* @return Индекс в списке мип-текстур textures
|
||
*/
|
||
public function getLevel(distance:Number, camera:Camera3D):int {
|
||
var level:int = Math.log(distance/(camera.focalLength*resolution))*1.442695040888963387;
|
||
if (level < 0) return 0; else if (level >= num) return num - 1;
|
||
return level;
|
||
}
|
||
}
|
||
}
|