mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2024-11-22 23:50:52 +01:00
Begin plane masks/door
This commit is contained in:
parent
79b662fdb9
commit
842a996b93
@ -1,14 +1,18 @@
|
||||
import { IAssetPlaneVisualizationLayer, IAssetRoomVisualizationData, IRoomGeometry, IRoomPlane, IVector3D } from '@nitrots/api';
|
||||
import { GetAssetManager } from '@nitrots/assets';
|
||||
import { TextureUtils, Vector3d } from '@nitrots/utils';
|
||||
import { Matrix, Point, Texture, TilingSprite } from 'pixi.js';
|
||||
import { Container, Matrix, Point, Sprite, Texture, TilingSprite } from 'pixi.js';
|
||||
import { RoomGeometry } from '../../../utils';
|
||||
import { RoomPlaneBitmapMask } from './RoomPlaneBitmapMask';
|
||||
import { RoomPlaneRectangleMask } from './RoomPlaneRectangleMask';
|
||||
import { PlaneMaskManager } from './mask';
|
||||
import { Randomizer } from './utils';
|
||||
|
||||
export class RoomPlane implements IRoomPlane
|
||||
{
|
||||
public static HORIZONTAL_ANGLE_DEFAULT: number = 45;
|
||||
public static VERTICAL_ANGLE_DEFAULT: number = 30;
|
||||
public static PLANE_GEOMETRY: IRoomGeometry = new RoomGeometry(64, new Vector3d(RoomPlane.HORIZONTAL_ANGLE_DEFAULT, RoomPlane.VERTICAL_ANGLE_DEFAULT), new Vector3d(-10, 0, 0));
|
||||
|
||||
public static TYPE_UNDEFINED: number = 0;
|
||||
public static TYPE_WALL: number = 1;
|
||||
@ -16,25 +20,26 @@ export class RoomPlane implements IRoomPlane
|
||||
public static TYPE_LANDSCAPE: number = 3;
|
||||
private static _uniqueIdCounter: number = 1;
|
||||
|
||||
private _disposed: boolean;
|
||||
private _disposed: boolean = false;
|
||||
private _randomSeed: number;
|
||||
private _origin: IVector3D;
|
||||
private _location: IVector3D;
|
||||
private _leftSide: IVector3D;
|
||||
private _rightSide: IVector3D;
|
||||
private _normal: IVector3D;
|
||||
private _secondaryNormals: IVector3D[];
|
||||
private _origin: IVector3D = new Vector3d();
|
||||
private _location: IVector3D = new Vector3d();
|
||||
private _leftSide: IVector3D = new Vector3d();
|
||||
private _rightSide: IVector3D = new Vector3d();
|
||||
private _normal: IVector3D = null;
|
||||
private _secondaryNormals: IVector3D[] = [];
|
||||
private _type: number;
|
||||
private _isVisible: boolean;
|
||||
private _offset: Point;
|
||||
private _relativeDepth: number;
|
||||
private _color: number;
|
||||
private _id: string;
|
||||
private _isVisible: boolean = false;
|
||||
private _offset: Point = new Point();
|
||||
private _relativeDepth: number = 0;
|
||||
private _color: number = 0;
|
||||
private _maskManager: PlaneMaskManager = null;
|
||||
private _id: string = null;
|
||||
private _uniqueId: number;
|
||||
private _cornerA: IVector3D;
|
||||
private _cornerB: IVector3D;
|
||||
private _cornerC: IVector3D;
|
||||
private _cornerD: IVector3D;
|
||||
private _cornerA: IVector3D = new Vector3d();
|
||||
private _cornerB: IVector3D = new Vector3d();
|
||||
private _cornerC: IVector3D = new Vector3d();
|
||||
private _cornerD: IVector3D = new Vector3d();
|
||||
private _textureOffsetX: number;
|
||||
private _textureOffsetY: number;
|
||||
private _textureMaxX: number;
|
||||
@ -42,29 +47,27 @@ export class RoomPlane implements IRoomPlane
|
||||
private _width: number = 0;
|
||||
private _height: number = 0;
|
||||
private _hasTexture: boolean = true;
|
||||
private _canBeVisible: boolean;
|
||||
private _canBeVisible: boolean = true;
|
||||
|
||||
private _useMask: boolean;
|
||||
private _bitmapMasks: RoomPlaneBitmapMask[] = [];
|
||||
private _rectangleMasks: RoomPlaneRectangleMask[] = [];
|
||||
private _maskChanged: boolean = false;
|
||||
private _bitmapMasksOld: RoomPlaneBitmapMask[] = [];
|
||||
private _rectangleMasksOld: RoomPlaneRectangleMask[] = [];
|
||||
|
||||
private _tilingSprite: TilingSprite = null;
|
||||
private _planeTexture: Texture = null;
|
||||
|
||||
constructor(origin: IVector3D, location: IVector3D, leftSide: IVector3D, rightSide: IVector3D, type: number, usesMask: boolean, secondaryNormals: IVector3D[], randomSeed: number, textureOffsetX: number = 0, textureOffsetY: number = 0, textureMaxX: number = 0, textureMaxY: number = 0)
|
||||
{
|
||||
this._secondaryNormals = [];
|
||||
this._randomSeed = randomSeed;
|
||||
this._origin = new Vector3d();
|
||||
this._origin.assign(origin);
|
||||
this._location = new Vector3d();
|
||||
this._location.assign(location);
|
||||
this._leftSide = new Vector3d();
|
||||
this._leftSide.assign(leftSide);
|
||||
this._rightSide = new Vector3d();
|
||||
this._rightSide.assign(rightSide);
|
||||
this._normal = Vector3d.crossProduct(this._leftSide, this._rightSide);
|
||||
|
||||
if(this._normal.length > 0)
|
||||
{
|
||||
this._normal.multiply((1 / this._normal.length));
|
||||
}
|
||||
if(this._normal.length > 0) this._normal.multiply((1 / this._normal.length));
|
||||
|
||||
if(secondaryNormals != null)
|
||||
{
|
||||
@ -79,24 +82,13 @@ export class RoomPlane implements IRoomPlane
|
||||
this._secondaryNormals.push(vector);
|
||||
}
|
||||
}
|
||||
this._disposed = false;
|
||||
this._isVisible = false;
|
||||
this._id = null;
|
||||
this._offset = new Point();
|
||||
this._relativeDepth = 0;
|
||||
|
||||
this._type = type;
|
||||
this._color = 0;
|
||||
this._canBeVisible = true;
|
||||
this._cornerA = new Vector3d();
|
||||
this._cornerB = new Vector3d();
|
||||
this._cornerC = new Vector3d();
|
||||
this._cornerD = new Vector3d();
|
||||
this._textureOffsetX = textureOffsetX;
|
||||
this._textureOffsetY = textureOffsetY;
|
||||
this._textureMaxX = textureMaxX;
|
||||
this._textureMaxY = textureMaxY;
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this._useMask = usesMask;
|
||||
this._uniqueId = ++RoomPlane._uniqueIdCounter;
|
||||
}
|
||||
|
||||
@ -174,14 +166,9 @@ export class RoomPlane implements IRoomPlane
|
||||
|
||||
Randomizer.setSeed(this._randomSeed);
|
||||
|
||||
const horizontalAngle = RoomPlane.HORIZONTAL_ANGLE_DEFAULT;
|
||||
const verticalAngle = RoomPlane.VERTICAL_ANGLE_DEFAULT;
|
||||
|
||||
geometry = new RoomGeometry(64, new Vector3d(horizontalAngle, verticalAngle), new Vector3d(-10, 0, 0));
|
||||
|
||||
let width = (this._leftSide.length * geometry.scale);
|
||||
let height = (this._rightSide.length * geometry.scale);
|
||||
const normal = geometry.getCoordinatePosition(this._normal);
|
||||
let width = (this._leftSide.length * RoomPlane.PLANE_GEOMETRY.scale);
|
||||
let height = (this._rightSide.length * RoomPlane.PLANE_GEOMETRY.scale);
|
||||
const normal = RoomPlane.PLANE_GEOMETRY.getCoordinatePosition(this._normal);
|
||||
|
||||
const getTextureAndColorForPlane = (planeId: string, planeType: number) =>
|
||||
{
|
||||
@ -207,7 +194,7 @@ export class RoomPlane implements IRoomPlane
|
||||
return parseInt(color, 16);
|
||||
};
|
||||
|
||||
return { texture, color: getRandomColor() };
|
||||
return { texture, color: planeColor };
|
||||
};
|
||||
|
||||
const planeData = getTextureAndColorForPlane(this._id, this._type);
|
||||
@ -218,9 +205,9 @@ export class RoomPlane implements IRoomPlane
|
||||
switch(this._type)
|
||||
{
|
||||
case RoomPlane.TYPE_FLOOR: {
|
||||
const _local_10 = geometry.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_11 = geometry.getScreenPoint(new Vector3d(0, (height / geometry.scale), 0));
|
||||
const _local_12 = geometry.getScreenPoint(new Vector3d((width / geometry.scale), 0, 0));
|
||||
const _local_10 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_11 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, (height / RoomPlane.PLANE_GEOMETRY.scale), 0));
|
||||
const _local_12 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d((width / RoomPlane.PLANE_GEOMETRY.scale), 0, 0));
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
@ -230,7 +217,7 @@ export class RoomPlane implements IRoomPlane
|
||||
width = Math.round(Math.abs((_local_10.x - _local_12.x)));
|
||||
height = Math.round(Math.abs((_local_10.x - _local_11.x)));
|
||||
|
||||
const _local_15 = (_local_10.x - geometry.getScreenPoint(new Vector3d(1, 0, 0)).x);
|
||||
const _local_15 = (_local_10.x - RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(1, 0, 0)).x);
|
||||
|
||||
x = (this._textureOffsetX * Math.trunc(Math.abs(_local_15)));
|
||||
y = (this._textureOffsetY * Math.trunc(Math.abs(_local_15)));
|
||||
@ -257,9 +244,9 @@ export class RoomPlane implements IRoomPlane
|
||||
break;
|
||||
}
|
||||
case RoomPlane.TYPE_WALL: {
|
||||
const _local_8 = geometry.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_9 = geometry.getScreenPoint(new Vector3d(0, 0, (height / geometry.scale)));
|
||||
const _local_10 = geometry.getScreenPoint(new Vector3d(0, (width / geometry.scale), 0));
|
||||
const _local_8 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_9 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, (height / RoomPlane.PLANE_GEOMETRY.scale)));
|
||||
const _local_10 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, (width / RoomPlane.PLANE_GEOMETRY.scale), 0));
|
||||
|
||||
if(_local_8 && _local_9 && _local_10)
|
||||
{
|
||||
@ -281,14 +268,14 @@ export class RoomPlane implements IRoomPlane
|
||||
break;
|
||||
}
|
||||
case RoomPlane.TYPE_LANDSCAPE: {
|
||||
const _local_13 = geometry.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_14 = geometry.getScreenPoint(new Vector3d(0, 0, 1));
|
||||
const _local_15 = geometry.getScreenPoint(new Vector3d(0, 1, 0));
|
||||
const _local_13 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 0));
|
||||
const _local_14 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 0, 1));
|
||||
const _local_15 = RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(0, 1, 0));
|
||||
|
||||
if(_local_13 && _local_14 && _local_15)
|
||||
{
|
||||
width = Math.round(Math.abs((((_local_13.x - _local_15.x) * width) / geometry.scale)));
|
||||
height = Math.round(Math.abs((((_local_13.y - _local_14.y) * height) / geometry.scale)));
|
||||
width = Math.round(Math.abs((((_local_13.x - _local_15.x) * width) / RoomPlane.PLANE_GEOMETRY.scale)));
|
||||
height = Math.round(Math.abs((((_local_13.y - _local_14.y) * height) / RoomPlane.PLANE_GEOMETRY.scale)));
|
||||
}
|
||||
|
||||
const renderMaxX = Math.trunc(this._textureMaxX * Math.abs((_local_13.x - _local_15.x)));
|
||||
@ -320,6 +307,8 @@ export class RoomPlane implements IRoomPlane
|
||||
}
|
||||
}
|
||||
|
||||
this.updateMask(planeSprite, geometry);
|
||||
|
||||
this._planeTexture = TextureUtils.createAndWriteRenderTexture(this._width, this._height, planeSprite, this.getMatrixForDimensions(width, height)) as Texture;
|
||||
|
||||
return true;
|
||||
@ -395,6 +384,183 @@ export class RoomPlane implements IRoomPlane
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public resetBitmapMasks(): void
|
||||
{
|
||||
if(this._disposed || !this._useMask || !this._bitmapMasks.length) return;
|
||||
|
||||
this._maskChanged = true;
|
||||
this._bitmapMasks = [];
|
||||
}
|
||||
|
||||
public addBitmapMask(maskType: string, leftSideLoc: number, rightSideLoc: number): boolean
|
||||
{
|
||||
if(!this._useMask) return false;
|
||||
|
||||
for(const mask of this._bitmapMasks)
|
||||
{
|
||||
if(!mask) continue;
|
||||
|
||||
if((((mask.type === maskType) && (mask.leftSideLoc === leftSideLoc)) && (mask.rightSideLoc === rightSideLoc))) return false;
|
||||
}
|
||||
|
||||
const mask = new RoomPlaneBitmapMask(maskType, leftSideLoc, rightSideLoc);
|
||||
|
||||
this._bitmapMasks.push(mask);
|
||||
this._maskChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public resetRectangleMasks(): void
|
||||
{
|
||||
if(!this._useMask || !this._rectangleMasks.length) return;
|
||||
|
||||
this._maskChanged = true;
|
||||
this._rectangleMasks = [];
|
||||
}
|
||||
|
||||
public addRectangleMask(leftLocation: number, rightLocation: number, leftLength: number, rightLength: number): boolean
|
||||
{
|
||||
if(this._useMask)
|
||||
{
|
||||
for(const mask of this._rectangleMasks)
|
||||
{
|
||||
if(!mask) continue;
|
||||
|
||||
if((((mask.leftSideLoc === leftLocation) && (mask.rightSideLoc === rightLocation)) && (mask.leftSideLength === leftLength)) && (mask.rightSideLength === rightLength)) return false;
|
||||
}
|
||||
|
||||
this._rectangleMasks.push(new RoomPlaneRectangleMask(leftLocation, rightLocation, leftLength, rightLength));
|
||||
this._maskChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private updateMaskChangeStatus(): void
|
||||
{
|
||||
if(!this._maskChanged) return;
|
||||
|
||||
let maskChanged = true;
|
||||
|
||||
if(this._bitmapMasks.length === this._bitmapMasksOld.length)
|
||||
{
|
||||
for(const mask of this._bitmapMasks)
|
||||
{
|
||||
if(!mask) continue;
|
||||
|
||||
let _local_6 = false;
|
||||
|
||||
for(const plane of this._bitmapMasksOld)
|
||||
{
|
||||
if(!plane) continue;
|
||||
|
||||
if(((plane.type === mask.type) && (plane.leftSideLoc === mask.leftSideLoc)) && (plane.rightSideLoc === mask.rightSideLoc))
|
||||
{
|
||||
_local_6 = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!_local_6)
|
||||
{
|
||||
maskChanged = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maskChanged = false;
|
||||
}
|
||||
|
||||
if(this._rectangleMasks.length > this._rectangleMasksOld.length) maskChanged = false;
|
||||
|
||||
if(maskChanged) this._maskChanged = false;
|
||||
}
|
||||
|
||||
private updateMask(sprite: Container, geometry: IRoomGeometry): void
|
||||
{
|
||||
if(!sprite || !geometry) return;
|
||||
|
||||
if(!this._useMask || ((!this._bitmapMasks.length && !this._rectangleMasks.length) && !this._maskChanged) || !this._maskManager) return;
|
||||
|
||||
this.updateMaskChangeStatus();
|
||||
|
||||
/* if(!this._maskBitmapData || (this._maskBitmapData.width !== width) || (this._maskBitmapData.height !== height))
|
||||
{
|
||||
this._maskBitmapData = this._textureCache.createAndFillRenderTexture(width, height, 'mask');
|
||||
this._maskChanged = true;
|
||||
} */
|
||||
|
||||
if(this._maskChanged)
|
||||
{
|
||||
this._bitmapMasksOld = [];
|
||||
this._rectangleMasksOld = [];
|
||||
|
||||
const normal = geometry.getCoordinatePosition(this._normal);
|
||||
|
||||
let type: string = null;
|
||||
let posX = 0;
|
||||
let posY = 0;
|
||||
let i = 0;
|
||||
|
||||
while(i < this._bitmapMasks.length)
|
||||
{
|
||||
const mask = this._bitmapMasks[i];
|
||||
|
||||
if(mask)
|
||||
{
|
||||
type = mask.type;
|
||||
posX = (sprite.width - ((sprite.width * mask.leftSideLoc) / this._leftSide.length));
|
||||
posY = (sprite.height - ((sprite.height * mask.rightSideLoc) / this._rightSide.length));
|
||||
|
||||
this._maskManager.updateMask(sprite, type, geometry.scale, normal, posX, posY);
|
||||
this._bitmapMasksOld.push(new RoomPlaneBitmapMask(type, mask.leftSideLoc, mask.rightSideLoc));
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while(i < this._rectangleMasks.length)
|
||||
{
|
||||
const rectMask = this._rectangleMasks[i];
|
||||
|
||||
if(rectMask)
|
||||
{
|
||||
posX = (sprite.width - ((sprite.width * rectMask.leftSideLoc) / this._leftSide.length));
|
||||
posY = (sprite.height - ((sprite.height * rectMask.rightSideLoc) / this._rightSide.length));
|
||||
|
||||
const wd = ((sprite.width * rectMask.leftSideLength) / this._leftSide.length);
|
||||
const ht = ((sprite.height * rectMask.rightSideLength) / this._rightSide.length);
|
||||
|
||||
const maskSprite = new Sprite(Texture.WHITE);
|
||||
|
||||
maskSprite.tint = 0x000000;
|
||||
maskSprite.width = wd;
|
||||
maskSprite.height = ht;
|
||||
maskSprite.position.set((posX - wd), (posY - ht));
|
||||
|
||||
//this._textureCache.writeToRenderTexture(sprite, this._maskBitmapData, false);
|
||||
|
||||
this._rectangleMasksOld.push(new RoomPlaneRectangleMask(rectMask.leftSideLength, rectMask.rightSideLoc, rectMask.leftSideLength, rectMask.rightSideLength));
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
this._maskChanged = false;
|
||||
}
|
||||
|
||||
//this.combineTextureMask(canvas, this._maskPixels);
|
||||
}
|
||||
|
||||
public get canBeVisible(): boolean
|
||||
{
|
||||
return this._canBeVisible;
|
||||
@ -462,6 +628,11 @@ export class RoomPlane implements IRoomPlane
|
||||
this._id = k;
|
||||
}
|
||||
|
||||
public set maskManager(k: PlaneMaskManager)
|
||||
{
|
||||
this._maskManager = k;
|
||||
}
|
||||
|
||||
public get uniqueId(): number
|
||||
{
|
||||
return this._uniqueId;
|
||||
|
@ -2,6 +2,9 @@ import { ToInt32, Vector3d } from '@nitrots/utils';
|
||||
import { Rectangle } from 'pixi.js';
|
||||
import { AlphaTolerance, IObjectVisualizationData, IPlaneVisualization, IRoomGeometry, IRoomObjectModel, IRoomObjectSprite, IRoomPlane, RoomObjectSpriteType, RoomObjectVariable } from '../../../../../api';
|
||||
import { RoomMapData } from '../../RoomMapData';
|
||||
import { RoomMapMaskData } from '../../RoomMapMaskData';
|
||||
import { RoomPlaneBitmapMaskData } from '../../RoomPlaneBitmapMaskData';
|
||||
import { RoomPlaneBitmapMaskParser } from '../../RoomPlaneBitmapMaskParser';
|
||||
import { RoomPlaneData } from '../../RoomPlaneData';
|
||||
import { RoomPlaneParser } from '../../RoomPlaneParser';
|
||||
import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization';
|
||||
@ -22,60 +25,39 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
public static LANDSCAPE_COLOR_BOTTOM: number = 0x999999;
|
||||
private static ROOM_DEPTH_OFFSET: number = 1000;
|
||||
|
||||
protected _data: RoomVisualizationData;
|
||||
protected _data: RoomVisualizationData = null;
|
||||
|
||||
private _roomPlaneParser: RoomPlaneParser;
|
||||
|
||||
private _geometryUpdateId: number;
|
||||
private _boundingRectangle: Rectangle;
|
||||
private _directionX: number;
|
||||
private _directionY: number;
|
||||
private _directionZ: number;
|
||||
private _floorThickness: number;
|
||||
private _wallThickness: number;
|
||||
private _holeUpdateTime: number;
|
||||
private _planes: RoomPlane[];
|
||||
private _visiblePlanes: RoomPlane[];
|
||||
private _visiblePlaneSpriteNumbers: number[];
|
||||
private _roomScale: number;
|
||||
private _colorBackgroundOnly: boolean;
|
||||
private _redColor: number;
|
||||
private _greenColor: number;
|
||||
private _blueColor: number;
|
||||
private _roomPlaneParser: RoomPlaneParser = new RoomPlaneParser();
|
||||
private _roomPlaneBitmapMaskParser: RoomPlaneBitmapMaskParser = new RoomPlaneBitmapMaskParser();
|
||||
private _geometryUpdateId: number = -1;
|
||||
private _boundingRectangle: Rectangle = null;
|
||||
private _directionX: number = 0;
|
||||
private _directionY: number = 0;
|
||||
private _directionZ: number = 0;
|
||||
private _floorThickness: number = 1;
|
||||
private _wallThickness: number = 1;
|
||||
private _holeUpdateTime: number = NaN;
|
||||
private _planes: RoomPlane[] = [];
|
||||
private _visiblePlanes: RoomPlane[] = [];
|
||||
private _visiblePlaneSpriteNumbers: number[] = [];
|
||||
private _roomScale: number = 0;
|
||||
private _colorBackgroundOnly: boolean = true;
|
||||
private _color: number = 0xFFFFFF;
|
||||
private _redColor: number = 0xFFFFFF;
|
||||
private _greenColor: number = 0xFFFFFF;
|
||||
private _blueColor: number = 0xFFFFFF;
|
||||
private _wallType: string = null;
|
||||
private _floorType: string = null;
|
||||
private _landscapeType: string = null;
|
||||
private _typeVisibility: boolean[];
|
||||
private _assetUpdateCounter: number;
|
||||
private _isPlaneSet: boolean;
|
||||
private _typeVisibility: boolean[] = [];
|
||||
private _assetUpdateCounter: number = 0;
|
||||
private _maskData: RoomMapMaskData = null;
|
||||
private _isPlaneSet: boolean = false;
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
||||
this._data = null;
|
||||
|
||||
this._roomPlaneParser = new RoomPlaneParser();
|
||||
|
||||
this._geometryUpdateId = -1;
|
||||
this._directionX = 0;
|
||||
this._directionY = 0;
|
||||
this._directionZ = 0;
|
||||
this._floorThickness = 1;
|
||||
this._wallThickness = 1;
|
||||
this._holeUpdateTime = NaN;
|
||||
this._planes = [];
|
||||
this._visiblePlanes = [];
|
||||
this._visiblePlaneSpriteNumbers = [];
|
||||
this._roomScale = 0;
|
||||
this._colorBackgroundOnly = true;
|
||||
this._redColor = 0xFF;
|
||||
this._greenColor = 0xFF;
|
||||
this._blueColor = 0xFF;
|
||||
this._typeVisibility = [];
|
||||
this._assetUpdateCounter = 0;
|
||||
this._isPlaneSet = false;
|
||||
|
||||
this._typeVisibility[RoomPlane.TYPE_UNDEFINED] = false;
|
||||
this._typeVisibility[RoomPlane.TYPE_FLOOR] = true;
|
||||
this._typeVisibility[RoomPlane.TYPE_WALL] = true;
|
||||
@ -112,8 +94,18 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
this._roomPlaneParser = null;
|
||||
}
|
||||
|
||||
if(this._roomPlaneBitmapMaskParser)
|
||||
{
|
||||
this._roomPlaneBitmapMaskParser.dispose();
|
||||
|
||||
this._roomPlaneBitmapMaskParser = null;
|
||||
}
|
||||
|
||||
|
||||
if(this._data)
|
||||
{
|
||||
this._data.clearCache();
|
||||
|
||||
this._data = null;
|
||||
}
|
||||
}
|
||||
@ -122,6 +114,10 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
{
|
||||
super.reset();
|
||||
|
||||
this._floorType = null;
|
||||
this._wallType = null;
|
||||
this._landscapeType = null;
|
||||
this._maskData = null;
|
||||
this._geometryUpdateId = -1;
|
||||
this._roomScale = 0;
|
||||
}
|
||||
@ -139,12 +135,18 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
|
||||
if(this.updateHole(objectModel)) needsUpdate = true;
|
||||
|
||||
this.initializeRoomPlanes();
|
||||
|
||||
if(this.updateMasks(objectModel)) needsUpdate = true;
|
||||
|
||||
if(!needsUpdate) return;
|
||||
|
||||
this.initializeRoomPlanes();
|
||||
this.updatePlaneTexturesAndVisibilities(objectModel);
|
||||
this.updatePlanes(geometry, geometryUpdate, time);
|
||||
if(this.updatePlaneTexturesAndVisibilities(objectModel)) needsUpdate = true;
|
||||
|
||||
if(this.updatePlanes(geometry, geometryUpdate, time)) needsUpdate = true;
|
||||
|
||||
if(needsUpdate)
|
||||
{
|
||||
let index = 0;
|
||||
|
||||
while(index < this._visiblePlanes.length)
|
||||
@ -176,6 +178,7 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateSpriteCounter++;
|
||||
|
||||
@ -259,6 +262,47 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
return (this.updatePlaneTypes(floorType, wallType, landscapeType) || this.updatePlaneVisibility(floorVisibility, wallVisibility, landscapeVisibility));
|
||||
}
|
||||
|
||||
private updateMasks(model: IRoomObjectModel): boolean
|
||||
{
|
||||
if(this.updateModelCounter === model.updateCounter) return false;
|
||||
|
||||
let didUpdate = false;
|
||||
|
||||
const planeMask = model.getValue<RoomMapMaskData>(RoomObjectVariable.ROOM_PLANE_MASK_XML);
|
||||
|
||||
if(planeMask !== this._maskData)
|
||||
{
|
||||
this.updatePlaneMasks(planeMask);
|
||||
|
||||
this._maskData = planeMask;
|
||||
|
||||
didUpdate = true;
|
||||
}
|
||||
|
||||
const backgroundColor = model.getValue<number>(RoomObjectVariable.ROOM_BACKGROUND_COLOR);
|
||||
|
||||
if(backgroundColor !== this._color)
|
||||
{
|
||||
this._color = backgroundColor;
|
||||
this._redColor = (this._color & 0xFF);
|
||||
this._greenColor = ((this._color >> 8) & 0xFF);
|
||||
this._blueColor = ((this._color >> 16) & 0xFF);
|
||||
|
||||
didUpdate = true;
|
||||
}
|
||||
|
||||
const backgroundOnly = (model.getValue<boolean>(RoomObjectVariable.ROOM_COLORIZE_BG_ONLY) || false);
|
||||
|
||||
if(backgroundOnly !== this._colorBackgroundOnly)
|
||||
{
|
||||
this._colorBackgroundOnly = backgroundOnly;
|
||||
|
||||
didUpdate = true;
|
||||
}
|
||||
|
||||
return didUpdate;
|
||||
}
|
||||
|
||||
private clearPlanes(): void
|
||||
{
|
||||
if(this._planes)
|
||||
@ -349,7 +393,26 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
landscapeOffsetX = (landscapeOffsetX + leftSide.length);
|
||||
}
|
||||
|
||||
if(plane) this._planes.push(plane);
|
||||
if(plane)
|
||||
{
|
||||
plane.maskManager = this._data.maskManager;
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this._roomPlaneParser.getPlaneMaskCount(index))
|
||||
{
|
||||
const _local_20 = this._roomPlaneParser.getPlaneMaskLeftSideLoc(index, i);
|
||||
const _local_21 = this._roomPlaneParser.getPlaneMaskRightSideLoc(index, i);
|
||||
const _local_22 = this._roomPlaneParser.getPlaneMaskLeftSideLength(index, i);
|
||||
const _local_23 = this._roomPlaneParser.getPlaneMaskRightSideLength(index, i);
|
||||
|
||||
plane.addRectangleMask(_local_20, _local_21, _local_22, _local_23);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
this._planes.push(plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -603,6 +666,109 @@ export class RoomVisualization extends RoomObjectSpriteVisualization implements
|
||||
return updated;
|
||||
}
|
||||
|
||||
protected updatePlaneMasks(maskData: RoomMapMaskData): void
|
||||
{
|
||||
if(!maskData) return;
|
||||
|
||||
this._roomPlaneBitmapMaskParser.initialize(maskData);
|
||||
|
||||
const _local_4: number[] = [];
|
||||
const _local_5: number[] = [];
|
||||
|
||||
let _local_6 = false;
|
||||
let index = 0;
|
||||
|
||||
while(index < this._planes.length)
|
||||
{
|
||||
const plane = this._planes[index];
|
||||
|
||||
if(plane)
|
||||
{
|
||||
plane.resetBitmapMasks();
|
||||
|
||||
if(plane.type === RoomPlane.TYPE_LANDSCAPE) _local_4.push(index);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
for(const mask of this._roomPlaneBitmapMaskParser.masks.values())
|
||||
{
|
||||
const maskType = this._roomPlaneBitmapMaskParser.getMaskType(mask);
|
||||
const maskLocation = this._roomPlaneBitmapMaskParser.getMaskLocation(mask);
|
||||
const maskCategory = this._roomPlaneBitmapMaskParser.getMaskCategory(mask);
|
||||
|
||||
if(maskLocation)
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < this._planes.length)
|
||||
{
|
||||
const plane = this._planes[i];
|
||||
|
||||
if((plane.type === RoomPlane.TYPE_WALL) || (plane.type === RoomPlane.TYPE_LANDSCAPE))
|
||||
{
|
||||
if(plane && plane.location && plane.normal)
|
||||
{
|
||||
const _local_14 = Vector3d.dif(maskLocation, plane.location);
|
||||
const _local_15 = Math.abs(Vector3d.scalarProjection(_local_14, plane.normal));
|
||||
|
||||
if(_local_15 < 0.01)
|
||||
{
|
||||
if(plane.leftSide && plane.rightSide)
|
||||
{
|
||||
const leftSideLoc = Vector3d.scalarProjection(_local_14, plane.leftSide);
|
||||
const rightSideLoc = Vector3d.scalarProjection(_local_14, plane.rightSide);
|
||||
|
||||
if((plane.type === RoomPlane.TYPE_WALL) || ((plane.type === RoomPlane.TYPE_LANDSCAPE) && (maskCategory === RoomPlaneBitmapMaskData.HOLE)))
|
||||
{
|
||||
plane.addBitmapMask(maskType, leftSideLoc, rightSideLoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(plane.type === RoomPlane.TYPE_LANDSCAPE)
|
||||
{
|
||||
if(!plane.canBeVisible) _local_6 = true;
|
||||
|
||||
plane.canBeVisible = true;
|
||||
|
||||
_local_5.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index = 0;
|
||||
|
||||
while(index < _local_4.length)
|
||||
{
|
||||
const planeIndex = _local_4[index];
|
||||
|
||||
if(_local_5.indexOf(planeIndex) < 0)
|
||||
{
|
||||
const plane = this._planes[planeIndex];
|
||||
|
||||
plane.canBeVisible = false;
|
||||
_local_6 = true;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if(_local_6)
|
||||
{
|
||||
this._visiblePlanes = [];
|
||||
this._visiblePlaneSpriteNumbers = [];
|
||||
}
|
||||
}
|
||||
|
||||
private updateSprite(sprite: IRoomObjectSprite, geometry: IRoomGeometry, plane: RoomPlane, _arg_3: string, relativeDepth: number): void
|
||||
{
|
||||
const offset = plane.offset;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { IAssetPlaneMaskData, IAssetPlaneTextureBitmap, IGraphicAssetCollection, IVector3D } from '@nitrots/api';
|
||||
import { TextureUtils } from '@nitrots/utils';
|
||||
import { Matrix, Point, Sprite, Texture } from 'pixi.js';
|
||||
import { CutMaskFilter } from '@nitrots/utils';
|
||||
import { Container, Matrix, Point } from 'pixi.js';
|
||||
import { PlaneMask } from './PlaneMask';
|
||||
import { PlaneMaskVisualization } from './PlaneMaskVisualization';
|
||||
|
||||
@ -141,7 +141,7 @@ export class PlaneMaskManager
|
||||
return graphicName;
|
||||
}
|
||||
|
||||
public updateMask(canvas: Texture, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean
|
||||
public updateMask(sprite: Container, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean
|
||||
{
|
||||
const mask = this._masks.get(type);
|
||||
|
||||
@ -157,6 +157,14 @@ export class PlaneMaskManager
|
||||
|
||||
const point = new Point((posX + asset.offsetX), (posY + asset.offsetY));
|
||||
|
||||
const filter = new CutMaskFilter({
|
||||
maskTexture: texture
|
||||
});
|
||||
|
||||
sprite.filters = [filter];
|
||||
|
||||
return true;
|
||||
|
||||
const matrix = new Matrix();
|
||||
|
||||
let xScale = 1;
|
||||
@ -185,7 +193,7 @@ export class PlaneMaskManager
|
||||
matrix.scale(xScale, ySkew);
|
||||
matrix.translate(tx, ty);
|
||||
|
||||
TextureUtils.writeToTexture(new Sprite(texture), canvas, false, matrix);
|
||||
//TextureUtils.writeToTexture(new Sprite(texture), canvas, false, matrix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -70,14 +70,7 @@ export class ExtendedSprite extends Sprite
|
||||
|
||||
const index = (dx + dy * textureSource.width) * 4;
|
||||
|
||||
const red = hitMap[index];
|
||||
const green = hitMap[index + 1];
|
||||
const blue = hitMap[index + 2];
|
||||
const alpha = hitMap[index + 3];
|
||||
|
||||
const result = (alpha >= this.alphaTolerance);
|
||||
|
||||
return result;
|
||||
return (hitMap[index + 3] >= this.alphaTolerance);
|
||||
}
|
||||
|
||||
private static generateHitMapForTextureSource(textureSource: TextureSource): boolean
|
||||
|
93
packages/utils/src/filters/CutMaskFilter.ts
Normal file
93
packages/utils/src/filters/CutMaskFilter.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js';
|
||||
|
||||
export interface CutTransparentAreaFilterOptions
|
||||
{
|
||||
maskTexture: Texture;
|
||||
}
|
||||
|
||||
export class CutMaskFilter extends Filter
|
||||
{
|
||||
public static readonly DEFAULT_OPTIONS: CutTransparentAreaFilterOptions = {
|
||||
maskTexture: Texture.WHITE,
|
||||
};
|
||||
|
||||
public uniforms: {
|
||||
uColor: Float32Array;
|
||||
uAlpha: number;
|
||||
uDimensions: Float32Array;
|
||||
};
|
||||
|
||||
constructor(options: CutTransparentAreaFilterOptions)
|
||||
{
|
||||
options = { ...CutMaskFilter.DEFAULT_OPTIONS, ...options };
|
||||
|
||||
if(!options.maskTexture) throw Error('No texture provided for mask filter');
|
||||
|
||||
const glProgram = GlProgram.from({
|
||||
vertex: `in vec2 aPosition;
|
||||
out vec2 vTextureCoord;
|
||||
|
||||
uniform vec4 uInputSize;
|
||||
uniform vec4 uOutputFrame;
|
||||
uniform vec4 uOutputTexture;
|
||||
|
||||
vec4 filterVertexPosition( void )
|
||||
{
|
||||
vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
|
||||
|
||||
position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
|
||||
position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
|
||||
|
||||
return vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec2 filterTextureCoord( void )
|
||||
{
|
||||
return aPosition * (uOutputFrame.zw * uInputSize.zw);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = filterVertexPosition();
|
||||
vTextureCoord = filterTextureCoord();
|
||||
}`,
|
||||
fragment: `varying vec2 vTextureCoord;
|
||||
|
||||
uniform sampler2D uSampler; // The sprite's texture
|
||||
uniform sampler2D maskTexture; // The mask texture
|
||||
|
||||
void main(void) {
|
||||
vec4 spriteColor = texture2D(uSampler, vTextureCoord);
|
||||
vec4 maskColor = texture2D(maskTexture, vTextureCoord);
|
||||
|
||||
// Use mask alpha to determine the transparency
|
||||
float alpha = maskColor.a;
|
||||
|
||||
// Apply the mask based on its alpha value
|
||||
// You can modify this logic to suit your masking criteria
|
||||
gl_FragColor = vec4(spriteColor.rgb, spriteColor.a * (1.0 - alpha));
|
||||
}`,
|
||||
name: 'cut-mask-filter',
|
||||
});
|
||||
|
||||
super({
|
||||
gpuProgram: null,
|
||||
glProgram,
|
||||
resources: {
|
||||
maskTexture: options.maskTexture
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(this, options);
|
||||
}
|
||||
|
||||
public apply(
|
||||
filterManager: FilterSystem,
|
||||
input: Texture,
|
||||
output: RenderSurface,
|
||||
clearMode: boolean,
|
||||
): void
|
||||
{
|
||||
filterManager.applyFilter(this, input, output, clearMode);
|
||||
}
|
||||
}
|
1
packages/utils/src/filters/index.ts
Normal file
1
packages/utils/src/filters/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './CutMaskFilter';
|
@ -24,4 +24,5 @@ export * from './PointMath';
|
||||
export * from './RoomId';
|
||||
export * from './TextureUtils';
|
||||
export * from './Vector3d';
|
||||
export * from './filters';
|
||||
export * from './motion';
|
||||
|
Loading…
Reference in New Issue
Block a user