Files
alternativa3d-archive/Alternativa3D7/7.0/alternativa/engine3d/core/MipMap.as
Pyogenics c2b65211bd Add A3D7
2024-09-28 17:35:38 +01:00

71 lines
3.0 KiB
ActionScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}