Merge remote-tracking branch 'origin/8.29.BugOmniShadow'

This commit is contained in:
Yaski
2012-05-10 18:35:02 +06:00
10 changed files with 541 additions and 348 deletions

View File

@@ -17,6 +17,6 @@ package alternativa {
/** /**
* Library version in the format: generation.feature-version.fix-version. * Library version in the format: generation.feature-version.fix-version.
*/ */
public static const version:String = "8.29.0"; public static const version:String = "8.30.0";
} }
} }

View File

@@ -3,7 +3,7 @@
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. * If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership. * You may add additional accurate notices of copyright ownership.
* *
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/ * It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */ * */
package alternativa.engine3d.core { package alternativa.engine3d.core {
@@ -13,7 +13,7 @@ package alternativa.engine3d.core {
import flash.geom.Vector3D; import flash.geom.Vector3D;
use namespace alternativa3d; use namespace alternativa3d;
/** /**
* Class stores object's bounding box object's local space. Generally, position of child objects isn't considered at BoundBox calculation. * Class stores object's bounding box object's local space. Generally, position of child objects isn't considered at BoundBox calculation.
* Ray intersection always made boundBox check at first, but it's possible to check on crossing boundBox only. * Ray intersection always made boundBox check at first, but it's possible to check on crossing boundBox only.
@@ -44,7 +44,7 @@ package alternativa.engine3d.core {
* Top face. * Top face.
*/ */
public var maxZ:Number = -1e+22; public var maxZ:Number = -1e+22;
/** /**
* Resets all bounds values to its initial state. * Resets all bounds values to its initial state.
@@ -57,33 +57,40 @@ package alternativa.engine3d.core {
maxY = -1e+22; maxY = -1e+22;
maxZ = -1e+22; maxZ = -1e+22;
} }
/** /**
* @private * @private
*/ */
alternativa3d function checkFrustumCulling(frustum:CullingPlane, culling:int):int { alternativa3d function checkFrustumCulling(frustum:CullingPlane, culling:int):int {
var side:int = 1; var side:int = 1;
for (var plane:CullingPlane = frustum; plane != null; plane = plane.next) { for (var plane:CullingPlane = frustum; plane != null; plane = plane.next) {
if (culling & side) { if (culling & side) {
if (plane.x >= 0) if (plane.y >= 0) if (plane.z >= 0) { if (plane.x >= 0)
if (maxX*plane.x + maxY*plane.y + maxZ*plane.z <= plane.offset) return -1; if (plane.y >= 0)
if (minX*plane.x + minY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side); if (plane.z >= 0) {
} else { if (maxX*plane.x + maxY*plane.y + maxZ*plane.z <= plane.offset) return -1;
if (maxX*plane.x + maxY*plane.y + minZ*plane.z <= plane.offset) return -1; if (minX*plane.x + minY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side);
if (minX*plane.x + minY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side); } else {
} else if (plane.z >= 0) { if (maxX*plane.x + maxY*plane.y + minZ*plane.z <= plane.offset) return -1;
if (maxX*plane.x + minY*plane.y + maxZ*plane.z <= plane.offset) return -1; if (minX*plane.x + minY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side);
if (minX*plane.x + maxY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side); }
} else { else
if (maxX*plane.x + minY*plane.y + minZ*plane.z <= plane.offset) return -1; if (plane.z >= 0) {
if (minX*plane.x + maxY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side); if (maxX*plane.x + minY*plane.y + maxZ*plane.z <= plane.offset) return -1;
} else if (plane.y >= 0) if (plane.z >= 0) { if (minX*plane.x + maxY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side);
if (minX*plane.x + maxY*plane.y + maxZ*plane.z <= plane.offset) return -1; } else {
if (maxX*plane.x + minY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side); if (maxX*plane.x + minY*plane.y + minZ*plane.z <= plane.offset) return -1;
} else { if (minX*plane.x + maxY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side);
if (minX*plane.x + maxY*plane.y + minZ*plane.z <= plane.offset) return -1; }
if (maxX*plane.x + minY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side); else if (plane.y >= 0)
} else if (plane.z >= 0) { if (plane.z >= 0) {
if (minX*plane.x + maxY*plane.y + maxZ*plane.z <= plane.offset) return -1;
if (maxX*plane.x + minY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side);
} else {
if (minX*plane.x + maxY*plane.y + minZ*plane.z <= plane.offset) return -1;
if (maxX*plane.x + minY*plane.y + maxZ*plane.z > plane.offset) culling &= (63 & ~side);
}
else if (plane.z >= 0) {
if (minX*plane.x + minY*plane.y + maxZ*plane.z <= plane.offset) return -1; if (minX*plane.x + minY*plane.y + maxZ*plane.z <= plane.offset) return -1;
if (maxX*plane.x + maxY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side); if (maxX*plane.x + maxY*plane.y + minZ*plane.z > plane.offset) culling &= (63 & ~side);
} else { } else {
@@ -95,9 +102,9 @@ package alternativa.engine3d.core {
} }
return culling; return culling;
} }
/** /**
* @private * @private
*/ */
alternativa3d function checkOcclusion(occluders:Vector.<Occluder>, occludersLength:int, transform:Transform3D):Boolean { alternativa3d function checkOcclusion(occluders:Vector.<Occluder>, occludersLength:int, transform:Transform3D):Boolean {
var ax:Number = transform.a*minX + transform.b*minY + transform.c*minZ + transform.d; var ax:Number = transform.a*minX + transform.b*minY + transform.c*minZ + transform.d;
@@ -140,9 +147,9 @@ package alternativa.engine3d.core {
} }
return false; return false;
} }
/** /**
* @private * @private
*/ */
alternativa3d function checkRays(origins:Vector.<Vector3D>, directions:Vector.<Vector3D>, raysLength:int):Boolean { alternativa3d function checkRays(origins:Vector.<Vector3D>, directions:Vector.<Vector3D>, raysLength:int):Boolean {
for (var i:int = 0; i < raysLength; i++) { for (var i:int = 0; i < raysLength; i++) {
@@ -269,7 +276,7 @@ package alternativa.engine3d.core {
if (c >= b || d <= a) return false; if (c >= b || d <= a) return false;
return true; return true;
} }
/** /**
* Duplicates an instance of <code>BoundBox</code>. * Duplicates an instance of <code>BoundBox</code>.
* @return New <code>BoundBox</code> instance with same set of properties. * @return New <code>BoundBox</code> instance with same set of properties.
@@ -284,7 +291,7 @@ package alternativa.engine3d.core {
res.maxZ = maxZ; res.maxZ = maxZ;
return res; return res;
} }
/** /**
* Returns a string representation of <code>BoundBox</code>. * Returns a string representation of <code>BoundBox</code>.
* @return A string representation of <code>BoundBox</code>. * @return A string representation of <code>BoundBox</code>.
@@ -292,6 +299,6 @@ package alternativa.engine3d.core {
public function toString():String { public function toString():String {
return "[BoundBox " + "X:[" + minX.toFixed(2) + ", " + maxX.toFixed(2) + "] Y:[" + minY.toFixed(2) + ", " + maxY.toFixed(2) + "] Z:[" + minZ.toFixed(2) + ", " + maxZ.toFixed(2) + "]]"; return "[BoundBox " + "X:[" + minX.toFixed(2) + ", " + maxX.toFixed(2) + "] Y:[" + minY.toFixed(2) + ", " + maxY.toFixed(2) + "] Z:[" + minZ.toFixed(2) + ", " + maxZ.toFixed(2) + "]]";
} }
} }
} }

View File

@@ -294,7 +294,7 @@ public class Camera3D extends Object3D {
} }
occludersLength = j; occludersLength = j;
occluders.length = j; occluders.length = j;
// Check light influence (?) // Check light influence
for (i = 0, j = 0; i < lightsLength; i++) { for (i = 0, j = 0; i < lightsLength; i++) {
light = lights[i]; light = lights[i];
light.localToCameraTransform.calculateInversion(light.cameraToLocalTransform); light.localToCameraTransform.calculateInversion(light.cameraToLocalTransform);
@@ -303,11 +303,12 @@ public class Camera3D extends Object3D {
light.green = ((light.color >> 8) & 0xFF) * light.intensity / 255; light.green = ((light.color >> 8) & 0xFF) * light.intensity / 255;
light.blue = (light.color & 0xFF) * light.intensity / 255; light.blue = (light.color & 0xFF) * light.intensity / 255;
// Debug // Debug
light.collectDraws(this, null, 0, false); light.collectDraws(this, null, 0, false);
if (debug && light.boundBox != null && (checkInDebug(light) & Debug.BOUNDS)) Debug.drawBoundBox(this, light.boundBox, light.localToCameraTransform); if (debug && light.boundBox != null && (checkInDebug(light) & Debug.BOUNDS)) Debug.drawBoundBox(this, light.boundBox, light.localToCameraTransform);
// Shadows preparing // Shadows preparing
if (light.shadow != null) { if (light.shadow != null) {
// TODO: Need check by occluders
light.shadow.process(this); light.shadow.process(this);
} }
lights[j] = light; lights[j] = light;
@@ -1096,10 +1097,10 @@ public class Camera3D extends Object3D {
value = 1000 * fpsUpdatePeriod / (time - previousPeriodTime); value = 1000 * fpsUpdatePeriod / (time - previousPeriodTime);
if (value > stageFrameRate) value = stageFrameRate; if (value > stageFrameRate) value = stageFrameRate;
mod = value * 100 % 100; mod = value * 100 % 100;
fpsTextField.text = int(value) + "." + ((mod >= 10) ? mod : ((mod > 0) ? ("0" + mod) : "00")); fpsTextField.text = int(value) + "." + ((mod >= 10) ? mod.toString() : ((mod > 0) ? ("0" + mod) : "00"));
value = 1000 / value; value = 1000 / value;
mod = value * 100 % 100; mod = value * 100 % 100;
frameTextField.text = int(value) + "." + ((mod >= 10) ? mod : ((mod > 0) ? ("0" + mod) : "00")); frameTextField.text = int(value) + "." + ((mod >= 10) ? mod.toString() : ((mod > 0) ? ("0" + mod) : "00"));
previousPeriodTime = time; previousPeriodTime = time;
fpsUpdateCounter = 0; fpsUpdateCounter = 0;
} }
@@ -1116,14 +1117,14 @@ public class Camera3D extends Object3D {
if (methodTimeCount > 0) { if (methodTimeCount > 0) {
value = methodTimeSum / methodTimeCount; value = methodTimeSum / methodTimeCount;
mod = value * 100 % 100; mod = value * 100 % 100;
timerTextField.text = int(value) + "." + ((mod >= 10) ? mod : ((mod > 0) ? ("0" + mod) : "00")); timerTextField.text = int(value) + "." + ((mod >= 10) ? mod.toString() : ((mod > 0) ? ("0" + mod) : "00"));
} else { } else {
timerTextField.text = ""; timerTextField.text = "";
} }
if (cpuTimeCount > 0) { if (cpuTimeCount > 0) {
value = cpuTimeSum / cpuTimeCount; value = cpuTimeSum / cpuTimeCount;
mod = value * 100 % 100; mod = value * 100 % 100;
cpuTextField.text = int(value) + "." + ((mod >= 10) ? mod : ((mod > 0) ? ("0" + mod) : "00")); cpuTextField.text = int(value) + "." + ((mod >= 10) ? mod.toString() : ((mod > 0) ? ("0" + mod) : "00"));
} else { } else {
cpuTextField.text = ""; cpuTextField.text = "";
} }
@@ -1138,7 +1139,7 @@ public class Camera3D extends Object3D {
var memory:int = System.totalMemory; var memory:int = System.totalMemory;
value = memory / 1048576; value = memory / 1048576;
mod = value * 100 % 100; mod = value * 100 % 100;
memoryTextField.text = int(value) + "." + ((mod >= 10) ? mod : ((mod > 0) ? ("0" + mod) : "00")); memoryTextField.text = int(value) + "." + ((mod >= 10) ? mod.toString() : ((mod > 0) ? ("0" + mod) : "00"));
// memory plot // memory plot
if (memory > maxMemory) maxMemory = memory; if (memory > maxMemory) maxMemory = memory;

View File

@@ -121,8 +121,9 @@ package alternativa.engine3d.core {
* @private * @private
*/ */
public function set shadow(value:Shadow):void { public function set shadow(value:Shadow):void {
if (_shadow != null) _shadow._light = null;
_shadow = value; _shadow = value;
_shadow._light = this; if (value != null) value._light = this;
} }
} }
} }

View File

@@ -13,8 +13,6 @@ package alternativa.engine3d.lights {
import alternativa.engine3d.core.Light3D; import alternativa.engine3d.core.Light3D;
import alternativa.engine3d.core.Object3D; import alternativa.engine3d.core.Object3D;
import alternativa.engine3d.core.Transform3D; import alternativa.engine3d.core.Transform3D;
import alternativa.engine3d.shadows.OmniLightShadow;
import alternativa.engine3d.shadows.Shadow;
use namespace alternativa3d; use namespace alternativa3d;
@@ -202,14 +200,5 @@ package alternativa.engine3d.lights {
return res; return res;
} }
/**
* @private
*/
override public function set shadow(value:Shadow):void {
_shadow = value;
_shadow._light = this;
var omniShadow:OmniLightShadow = value as OmniLightShadow;
if (omniShadow!=null) omniShadow.setBoundSize(this.attenuationEnd*1.5);
}
} }
} }

View File

@@ -467,13 +467,22 @@ package alternativa.engine3d.materials {
// i3 - ambient // i3 - ambient
// i2 - shadow-test // i2 - shadow-test
source.push("mul t0.xw, t0.xw, i2.xw"); source.push("mul t0.xw, t0.xwww, i2.xxxx");
source.push("mul t0.xyz, c1.xyz, t0.xxx"); // t = color*t source.push("mul t0.xyz, c1.xyz, t0.xxx"); // t = color*t
source.push("mul t1.xyz, t0.xyz, t1.w"); source.push("mul t1.xyz, t0.xyz, t1.w");
source.push("add o1.xyz, o1.xyz, t1.xyz"); source.push("add o1.xyz, o1.xyz, t1.xyz");
source.push("mul t0.xyz, t0.xyz, t0.www"); source.push("mul t0.xyz, t0.xyz, t0.www");
source.push("add o0.xyz, t0.xyz, i3.xyz"); source.push("add o0.xyz, t0.xyz, i3.xyz");
// source.push("mov o1, t1");
// source.push("mov o1, c1");
// source.push("mov o1, i2");
// source.push("mov o1, i3");
// source.push("sub o1, t0, t0");
//
// source.push("mov o0.xyz, i2.x");
// source.push("div o0.w, i2.x, i2.x");
} else { } else {
// Считаем вектор из точки к свету // Считаем вектор из точки к свету
@@ -1075,6 +1084,7 @@ package alternativa.engine3d.materials {
var j:int; var j:int;
var lightLengthInGroup:int; var lightLengthInGroup:int;
var isFirstGroup:Boolean = true; var isFirstGroup:Boolean = true;
var j:int;
for (i = 0; i < groupsCount; i++) { for (i = 0; i < groupsCount; i++) {
var lightGroup:Vector.<Light3D> = groups[i]; var lightGroup:Vector.<Light3D> = groups[i];
lightLengthInGroup = lightGroup.length; lightLengthInGroup = lightGroup.length;

View File

@@ -24,7 +24,7 @@ package alternativa.engine3d.objects {
/** /**
* @private * @private
* A joint transform matrix. * A joint transform matrix. Geometry -> Joint -> Skin
*/ */
alternativa3d var jointTransform:Transform3D = new Transform3D(); alternativa3d var jointTransform:Transform3D = new Transform3D();

View File

@@ -74,6 +74,8 @@ package alternativa.engine3d.objects {
} }
} }
// TODO: Add removeSurface() method
/** /**
* Adds <code>Surface</code> to <code>Mesh</code> object. * Adds <code>Surface</code> to <code>Mesh</code> object.
* @param material Material of the surface. * @param material Material of the surface.

View File

@@ -30,7 +30,7 @@ package alternativa.engine3d.shadows {
import alternativa.engine3d.resources.ExternalTextureResource; import alternativa.engine3d.resources.ExternalTextureResource;
import alternativa.engine3d.resources.Geometry; import alternativa.engine3d.resources.Geometry;
import alternativa.engine3d.resources.TextureResource; import alternativa.engine3d.resources.TextureResource;
import flash.display3D.Context3D; import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType; import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DTextureFormat; import flash.display3D.Context3DTextureFormat;
@@ -56,13 +56,12 @@ package alternativa.engine3d.shadows {
private var renderer:Renderer = new Renderer(); private var renderer:Renderer = new Renderer();
/**
* Debug mode.
*/
/** /**
* Degree of correcting offset of shadow map space. It need for getting rid of self-shadowing artifacts. * Degree of correcting offset of shadow map space. It need for getting rid of self-shadowing artifacts.
*/ */
public var biasMultiplier:Number = 0.99; public var biasMultiplier:Number = 0.97;
private static const DIFFERENCE_MULTIPLIER:Number = 32768;
// TODO: implement property parent // TODO: implement property parent
@@ -256,6 +255,7 @@ package alternativa.engine3d.shadows {
override alternativa3d function process(camera:Camera3D):void { override alternativa3d function process(camera:Camera3D):void {
var i:int; var i:int;
var object:Object3D; var object:Object3D;
// TODO: realize culling
// Clipping of casters, that have shadows which are invisible. // Clipping of casters, that have shadows which are invisible.
var numActualCasters:int = 0; var numActualCasters:int = 0;
for (i = 0; i < _casters.length; i++) { for (i = 0; i < _casters.length; i++) {
@@ -351,6 +351,8 @@ package alternativa.engine3d.shadows {
shadowMap = camera.context3D.createTexture(_mapSize, _mapSize, Context3DTextureFormat.BGRA, true); shadowMap = camera.context3D.createTexture(_mapSize, _mapSize, Context3DTextureFormat.BGRA, true);
debugTexture._texture = shadowMap; debugTexture._texture = shadowMap;
} }
// TODO Don't clear if there was no casters
camera.context3D.setRenderToTexture(shadowMap, true); camera.context3D.setRenderToTexture(shadowMap, true);
camera.context3D.clear(1, 0, 0, 0.3); camera.context3D.clear(1, 0, 0, 0.3);
@@ -369,23 +371,21 @@ package alternativa.engine3d.shadows {
camera.context3D.setRenderToBackBuffer(); camera.context3D.setRenderToBackBuffer();
if (debug) { if (debug) {
if (numActualCasters > 0) { if (debugPlane == null) {
if (debugPlane == null) { debugPlane = createDebugPlane(debugMaterial, camera.context3D);
debugPlane = createDebugPlane(debugMaterial, camera.context3D);
}
// Form transformation matrix for debugPlane
debugPlane.transform.compose((frustumMinX + frustumMaxX) / 2, (frustumMinY + frustumMaxY) / 2, frustumMinZ, 0, 0, 0, (frustumMaxX - frustumMinX), (frustumMaxY - frustumMinY), 1);
debugPlane.localToCameraTransform.combine(_light.localToCameraTransform, debugPlane.transform);
// Draw
var debugSurface:Surface = debugPlane._surfaces[0];
debugSurface.material.collectDraws(camera, debugSurface, debugPlane.geometry, emptyLightVector, 0, false, -1);
// Form transformation matrix for debugPlane
debugPlane.transform.compose((frustumMinX + frustumMaxX) / 2, (frustumMinY + frustumMaxY) / 2, frustumMaxZ, 0, 0, 0, (frustumMaxX - frustumMinX), (frustumMaxY - frustumMinY), 1);
debugPlane.localToCameraTransform.combine(_light.localToCameraTransform, debugPlane.transform);
debugSurface.material.collectDraws(camera, debugSurface, debugPlane.geometry, emptyLightVector, 0, false, -1);
} }
// Form transformation matrix for debugPlane
debugPlane.transform.compose((frustumMinX + frustumMaxX) / 2, (frustumMinY + frustumMaxY) / 2, frustumMinZ, 0, 0, 0, (frustumMaxX - frustumMinX), (frustumMaxY - frustumMinY), 1);
debugPlane.localToCameraTransform.combine(_light.localToCameraTransform, debugPlane.transform);
// Draw
var debugSurface:Surface = debugPlane._surfaces[0];
debugSurface.material.collectDraws(camera, debugSurface, debugPlane.geometry, emptyLightVector, 0, false, -1);
// Form transformation matrix for debugPlane
debugPlane.transform.compose((frustumMinX + frustumMaxX) / 2, (frustumMinY + frustumMaxY) / 2, frustumMaxZ, 0, 0, 0, (frustumMaxX - frustumMinX), (frustumMaxY - frustumMinY), 1);
debugPlane.localToCameraTransform.combine(_light.localToCameraTransform, debugPlane.transform);
debugSurface.material.collectDraws(camera, debugSurface, debugPlane.geometry, emptyLightVector, 0, false, -1);
tempBounds.minX = frustumMinX; tempBounds.minX = frustumMinX;
tempBounds.maxX = frustumMaxX; tempBounds.maxX = frustumMaxX;
@@ -718,16 +718,15 @@ package alternativa.engine3d.shadows {
drawUnit.setVertexConstantsFromTransform(vertexLinker.getVariableIndex("cUVProjection"), objectToShadowMapTransform); drawUnit.setVertexConstantsFromTransform(vertexLinker.getVariableIndex("cUVProjection"), objectToShadowMapTransform);
// Устанавливаем шедоумапу // Устанавливаем шедоумапу
drawUnit.setTextureAt(fragmentLinker.getVariableIndex("sShadowMap"), shadowMap); drawUnit.setTextureAt(fragmentLinker.getVariableIndex("sShadowMap"), shadowMap);
// TODO: сделать множитель более корректный. Возможно 65536 (разрешающая способность глубины буфера).
// Устанавливаем коеффициенты // Устанавливаем коеффициенты
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cConstants"), -255*10000, -10000, biasMultiplier*255*10000, 1/16); drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cConstants"), -255*DIFFERENCE_MULTIPLIER, -DIFFERENCE_MULTIPLIER, biasMultiplier*255*DIFFERENCE_MULTIPLIER, 1/16);
if (_pcfOffset > 0) { if (_pcfOffset > 0) {
var offset1:Number = _pcfOffset/_mapSize; var offset1:Number = _pcfOffset/_mapSize;
var offset2:Number = offset1/3; var offset2:Number = offset1/3;
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cPCFOffsets"), -offset1, -offset2, offset2, offset1); drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cPCFOffsets"), -offset1, -offset2, offset2, offset1);
} }
drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cDist"), 0.9999, 10000, 1); drawUnit.setFragmentConstantsFromNumbers(fragmentLinker.getVariableIndex("cDist"), 0.9999, DIFFERENCE_MULTIPLIER, 1);
} }
private static function getVShader():Procedure { private static function getVShader():Procedure {

File diff suppressed because it is too large Load Diff