Files
alternativa3d-archive/Alternativa3D2/2.0/com/alternativagame/engine3d/skin/SpriteSkin.as
2024-10-05 12:11:16 +01:00

131 lines
4.4 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 com.alternativagame.engine3d.skin {
import com.alternativagame.engine3d.Math3D;
import com.alternativagame.engine3d.Matrix3D;
import com.alternativagame.engine3d.engine3d;
import com.alternativagame.engine3d.material.SpriteMaterial;
import com.alternativagame.engine3d.material.SpritePhase;
import com.alternativagame.engine3d.object.Object3D;
import com.alternativagame.engine3d.object.SkinObject3D;
import com.alternativagame.engine3d.object.Sprite3D;
import com.alternativagame.type.RGB;
import com.alternativagame.type.Vector;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
use namespace engine3d;
public class SpriteSkin extends ObjectSkin {
use namespace engine3d;
// Битмапа
private var bitmap:Bitmap;
public function SpriteSkin(object:Sprite3D) {
super(object);
bitmap = new Bitmap();
addChild(bitmap);
}
private function viewAngle(vector:Vector):Number {
var len:Number = Math3D.vectorLength(vector);
// Если вектор нулевой, угол - 0 градусов
var cos:Number = (len != 0) ? (vector.y / len) : 1;
return Math.acos(cos);
}
override engine3d function draw():void {
super.draw();
var objTransform:Matrix3D = object.transform.clone();
objTransform.d = 0;
objTransform.h = 0;
objTransform.l = 0;
var material:SpriteMaterial = SpriteMaterial(this.material);
// Угол оси Z с вектором камеры
var pitchAngle:Number = viewAngle(new Vector(objTransform.c, objTransform.g, objTransform.k)) - Math.PI/2;
// Угол оси X с вектором камеры
var yawAngle:Number = viewAngle(new Vector(objTransform.a, objTransform.e, objTransform.i));
if (objTransform.f > 0) yawAngle = -yawAngle;
yawAngle += Math.PI/2;
// Находим подходящую фазу
var phase:SpritePhase = material.getPhase(Sprite3D(object).state, Math3D.toDegree(pitchAngle), Math3D.toDegree(yawAngle));
if (phase != null) {
bitmap.bitmapData = phase.bitmapData;
bitmap.smoothing = material.smoothing;
// Матрица преобразования скина
var matrix:Matrix = new Matrix();
matrix.tx = x;
matrix.ty = y;
var pivot:Point = new Point();
// Трансформация в зависимости от флагов
if (material.scale || material.rotate) {
var m:Matrix3D = Math3D.combineMatrix(objTransform, phase.transform);
}
if (material.scale) {
if (material.rotate) {
// Полная трансформация
matrix.a = m.a;
matrix.b = -m.i;
matrix.c = -m.c;
matrix.d = m.k;
} else {
// Только масштабирование
matrix.a = Math.sqrt(m.a*m.a + m.c*m.c);
matrix.d = Math.sqrt(m.i*m.i + m.k*m.k);
}
} else {
if (material.rotate) {
// Только поворот
var lenX:Number = Math.sqrt(m.a*m.a + m.c*m.c);
var ma:Number = m.a/lenX;
var mc:Number = m.c/lenX;
matrix.a = ma;
matrix.b = mc;
matrix.c = -mc;
matrix.d = ma;
}
}
// Наложить матрицу на битмапу
bitmap.x = -phase.pivot.x;
bitmap.y = -phase.pivot.y;
transform.matrix = matrix;
} else {
bitmap.bitmapData = null;
}
}
override engine3d function light():void {
var color:RGB = SkinObject3D(object).lightColor.clone();
// Добавить самосвечение
var selfIllumination:RGB = SpriteMaterial(this.material).selfIllumination;
color.add(selfIllumination);
var redMultiplier:Number = (color.red/5 + color.red*0.6 + 30) / 127;
var greenMultiplier:Number = (color.green/5 + color.green*0.6 + 30) / 127;
var blueMultiplier:Number = (color.blue/5 + color.blue*0.6 + 30) / 127;
var redOffset:Number = (color.red - 127) * 0.65;
var greenOffset:Number = (color.green - 127) * 0.65;
var blueOffset:Number = (color.blue - 127) * 0.65;
transform.colorTransform = new ColorTransform(redMultiplier, greenMultiplier, blueMultiplier, alpha, redOffset, greenOffset, blueOffset);
}
}
}