mirror of
https://github.com/billsonnn/nitro-renderer.git
synced 2025-02-18 10:52:36 +01:00
Masks now work
This commit is contained in:
parent
842a996b93
commit
2f01259b46
@ -1,6 +1,6 @@
|
|||||||
import { IAssetPlaneVisualizationLayer, IAssetRoomVisualizationData, IRoomGeometry, IRoomPlane, IVector3D } from '@nitrots/api';
|
import { IAssetPlaneVisualizationLayer, IAssetRoomVisualizationData, IRoomGeometry, IRoomPlane, IVector3D } from '@nitrots/api';
|
||||||
import { GetAssetManager } from '@nitrots/assets';
|
import { GetAssetManager } from '@nitrots/assets';
|
||||||
import { TextureUtils, Vector3d } from '@nitrots/utils';
|
import { GetRenderer, PlaneMaskFilter, TextureUtils, Vector3d } from '@nitrots/utils';
|
||||||
import { Container, Matrix, Point, Sprite, Texture, TilingSprite } from 'pixi.js';
|
import { Container, Matrix, Point, Sprite, Texture, TilingSprite } from 'pixi.js';
|
||||||
import { RoomGeometry } from '../../../utils';
|
import { RoomGeometry } from '../../../utils';
|
||||||
import { RoomPlaneBitmapMask } from './RoomPlaneBitmapMask';
|
import { RoomPlaneBitmapMask } from './RoomPlaneBitmapMask';
|
||||||
@ -48,6 +48,7 @@ export class RoomPlane implements IRoomPlane
|
|||||||
private _height: number = 0;
|
private _height: number = 0;
|
||||||
private _hasTexture: boolean = true;
|
private _hasTexture: boolean = true;
|
||||||
private _canBeVisible: boolean = true;
|
private _canBeVisible: boolean = true;
|
||||||
|
private _geometryUpdateId: number = -1;
|
||||||
|
|
||||||
private _useMask: boolean;
|
private _useMask: boolean;
|
||||||
private _bitmapMasks: RoomPlaneBitmapMask[] = [];
|
private _bitmapMasks: RoomPlaneBitmapMask[] = [];
|
||||||
@ -56,6 +57,7 @@ export class RoomPlane implements IRoomPlane
|
|||||||
private _bitmapMasksOld: RoomPlaneBitmapMask[] = [];
|
private _bitmapMasksOld: RoomPlaneBitmapMask[] = [];
|
||||||
private _rectangleMasksOld: RoomPlaneRectangleMask[] = [];
|
private _rectangleMasksOld: RoomPlaneRectangleMask[] = [];
|
||||||
|
|
||||||
|
private _planeSprite: TilingSprite = null;
|
||||||
private _planeTexture: Texture = 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)
|
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)
|
||||||
@ -111,205 +113,248 @@ export class RoomPlane implements IRoomPlane
|
|||||||
{
|
{
|
||||||
if(!geometry || this._disposed) return false;
|
if(!geometry || this._disposed) return false;
|
||||||
|
|
||||||
let cosAngle = 0;
|
let geometryChanged = false;
|
||||||
|
|
||||||
cosAngle = Vector3d.cosAngle(geometry.directionAxis, this.normal);
|
if(this._geometryUpdateId != geometry.updateId) geometryChanged = true;
|
||||||
|
|
||||||
if(cosAngle > -0.001)
|
if(!geometryChanged || !this._canBeVisible)
|
||||||
{
|
{
|
||||||
if(this._isVisible)
|
if(!this.visible) return false;
|
||||||
{
|
|
||||||
this._isVisible = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = 0;
|
if(geometryChanged)
|
||||||
|
|
||||||
while(i < this._secondaryNormals.length)
|
|
||||||
{
|
{
|
||||||
cosAngle = Vector3d.cosAngle(geometry.directionAxis, this._secondaryNormals[i]);
|
let cosAngle = 0;
|
||||||
|
|
||||||
|
cosAngle = Vector3d.cosAngle(geometry.directionAxis, this.normal);
|
||||||
|
|
||||||
if(cosAngle > -0.001)
|
if(cosAngle > -0.001)
|
||||||
{
|
{
|
||||||
if(this._isVisible)
|
if(this._isVisible)
|
||||||
{
|
{
|
||||||
this._isVisible = false;
|
this._isVisible = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
let i = 0;
|
||||||
}
|
|
||||||
|
|
||||||
this.updateCorners(geometry);
|
while(i < this._secondaryNormals.length)
|
||||||
|
|
||||||
let relativeDepth = (Math.max(this._cornerA.z, this._cornerB.z, this._cornerC.z, this._cornerD.z) - geometry.getScreenPosition(this._origin).z);
|
|
||||||
|
|
||||||
switch(this._type)
|
|
||||||
{
|
|
||||||
case RoomPlane.TYPE_FLOOR:
|
|
||||||
relativeDepth = (relativeDepth - ((this._location.z + Math.min(0, this._leftSide.z, this._rightSide.z)) * 8));
|
|
||||||
break;
|
|
||||||
case RoomPlane.TYPE_LANDSCAPE:
|
|
||||||
relativeDepth = (relativeDepth + 0.02);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._relativeDepth = relativeDepth;
|
|
||||||
this._isVisible = true;
|
|
||||||
|
|
||||||
Randomizer.setSeed(this._randomSeed);
|
|
||||||
|
|
||||||
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) =>
|
|
||||||
{
|
|
||||||
const dataType: keyof IAssetRoomVisualizationData = (planeType === RoomPlane.TYPE_FLOOR) ? 'floorData' : (planeType === RoomPlane.TYPE_WALL) ? 'wallData' : 'landscapeData';
|
|
||||||
|
|
||||||
const roomCollection = GetAssetManager().getCollection('room');
|
|
||||||
const planeVisualizationData = roomCollection?.data?.roomVisualization?.[dataType];
|
|
||||||
const planeVisualization = planeVisualizationData?.planes?.find(plane => (plane.id === planeId))?.visualizations?.[0];
|
|
||||||
const planeLayer = planeVisualization?.allLayers?.[0] as IAssetPlaneVisualizationLayer;
|
|
||||||
const planeMaterialId = planeLayer?.materialId;
|
|
||||||
const planeColor = planeLayer?.color;
|
|
||||||
const planeAssetName = planeVisualizationData?.textures?.find(texture => (texture.id === planeMaterialId))?.bitmaps?.[0]?.assetName;
|
|
||||||
const texture = GetAssetManager().getAsset(planeAssetName)?.texture;
|
|
||||||
|
|
||||||
const getRandomColor = () =>
|
|
||||||
{
|
{
|
||||||
const letters = '0123456789ABCDEF';
|
cosAngle = Vector3d.cosAngle(geometry.directionAxis, this._secondaryNormals[i]);
|
||||||
let color = '0x';
|
|
||||||
for(let i = 0; i < 6; i++)
|
if(cosAngle > -0.001)
|
||||||
{
|
{
|
||||||
color += letters[Math.floor(Math.random() * 16)];
|
if(this._isVisible)
|
||||||
|
{
|
||||||
|
this._isVisible = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return parseInt(color, 16);
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateCorners(geometry);
|
||||||
|
|
||||||
|
let relativeDepth = (Math.max(this._cornerA.z, this._cornerB.z, this._cornerC.z, this._cornerD.z) - geometry.getScreenPosition(this._origin).z);
|
||||||
|
|
||||||
|
switch(this._type)
|
||||||
|
{
|
||||||
|
case RoomPlane.TYPE_FLOOR:
|
||||||
|
relativeDepth = (relativeDepth - ((this._location.z + Math.min(0, this._leftSide.z, this._rightSide.z)) * 8));
|
||||||
|
break;
|
||||||
|
case RoomPlane.TYPE_LANDSCAPE:
|
||||||
|
relativeDepth = (relativeDepth + 0.02);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._relativeDepth = relativeDepth;
|
||||||
|
this._isVisible = true;
|
||||||
|
this._geometryUpdateId = geometry.updateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(geometryChanged)
|
||||||
|
{
|
||||||
|
Randomizer.setSeed(this._randomSeed);
|
||||||
|
|
||||||
|
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) =>
|
||||||
|
{
|
||||||
|
const dataType: keyof IAssetRoomVisualizationData = (planeType === RoomPlane.TYPE_FLOOR) ? 'floorData' : (planeType === RoomPlane.TYPE_WALL) ? 'wallData' : 'landscapeData';
|
||||||
|
|
||||||
|
const roomCollection = GetAssetManager().getCollection('room');
|
||||||
|
const planeVisualizationData = roomCollection?.data?.roomVisualization?.[dataType];
|
||||||
|
const planeVisualization = planeVisualizationData?.planes?.find(plane => (plane.id === planeId))?.visualizations?.[0];
|
||||||
|
const planeLayer = planeVisualization?.allLayers?.[0] as IAssetPlaneVisualizationLayer;
|
||||||
|
const planeMaterialId = planeLayer?.materialId;
|
||||||
|
const planeColor = planeLayer?.color;
|
||||||
|
const planeAssetName = planeVisualizationData?.textures?.find(texture => (texture.id === planeMaterialId))?.bitmaps?.[0]?.assetName;
|
||||||
|
const texture = GetAssetManager().getAsset(planeAssetName)?.texture;
|
||||||
|
|
||||||
|
const getRandomColor = () =>
|
||||||
|
{
|
||||||
|
const letters = '0123456789ABCDEF';
|
||||||
|
let color = '0x';
|
||||||
|
for(let i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
color += letters[Math.floor(Math.random() * 16)];
|
||||||
|
}
|
||||||
|
return parseInt(color, 16);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { texture, color: planeColor };
|
||||||
};
|
};
|
||||||
|
|
||||||
return { texture, color: planeColor };
|
const planeData = getTextureAndColorForPlane(this._id, this._type);
|
||||||
};
|
const texture = this._hasTexture ? planeData.texture ?? Texture.WHITE : Texture.WHITE;
|
||||||
|
|
||||||
const planeData = getTextureAndColorForPlane(this._id, this._type);
|
switch(this._type)
|
||||||
const texture = this._hasTexture ? planeData.texture ?? Texture.WHITE : Texture.WHITE;
|
{
|
||||||
|
case RoomPlane.TYPE_FLOOR: {
|
||||||
|
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 planeSprite: TilingSprite = null;
|
let x = 0;
|
||||||
|
let y = 0;
|
||||||
|
|
||||||
switch(this._type)
|
if(_local_10 && _local_11 && _local_12)
|
||||||
|
{
|
||||||
|
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 - 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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if((x !== 0) || (y !== 0))
|
||||||
|
{
|
||||||
|
while(x < 0) x += texture.width;
|
||||||
|
|
||||||
|
while(y < 0) y += texture.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._planeSprite = new TilingSprite({
|
||||||
|
texture,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
tint: planeData.color,
|
||||||
|
tilePosition: {
|
||||||
|
x: (x % texture.width) + (this._textureOffsetX * texture.width),
|
||||||
|
y: (y % texture.height) + (this._textureOffsetY * texture.height)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RoomPlane.TYPE_WALL: {
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
width = Math.round(Math.abs((_local_8.x - _local_10.x)));
|
||||||
|
height = Math.round(Math.abs((_local_8.y - _local_9.y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._planeSprite = new TilingSprite({
|
||||||
|
texture,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
tint: planeData.color,
|
||||||
|
tilePosition: {
|
||||||
|
x: (this._textureOffsetX * texture.width),
|
||||||
|
y: (this._textureOffsetY * texture.height)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RoomPlane.TYPE_LANDSCAPE: {
|
||||||
|
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) / 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)));
|
||||||
|
const renderMaxY = Math.trunc(this._textureMaxY * Math.abs((_local_13.y - _local_14.y)));
|
||||||
|
|
||||||
|
const renderOffsetX = Math.trunc(this._textureOffsetX * Math.abs((_local_13.x - _local_15.x)));
|
||||||
|
const renderOffsetY = Math.trunc(this._textureOffsetY * Math.abs((_local_13.y - _local_14.y)));
|
||||||
|
|
||||||
|
this._planeSprite = new TilingSprite({
|
||||||
|
texture,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
tilePosition: {
|
||||||
|
x: renderOffsetX,
|
||||||
|
y: renderOffsetY
|
||||||
|
},
|
||||||
|
tint: planeData.color,
|
||||||
|
applyAnchorToTexture: true
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
this._planeSprite = new TilingSprite({
|
||||||
|
texture: Texture.WHITE,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
applyAnchorToTexture: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._planeSprite.allowChildren = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const maskChanged = this._maskChanged;
|
||||||
|
|
||||||
|
if(maskChanged)
|
||||||
{
|
{
|
||||||
case RoomPlane.TYPE_FLOOR: {
|
this._planeSprite.removeChildren();
|
||||||
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;
|
this.updateMask(this._planeSprite, geometry);
|
||||||
let y = 0;
|
}
|
||||||
|
|
||||||
if(_local_10 && _local_11 && _local_12)
|
if(this._planeTexture)
|
||||||
{
|
{
|
||||||
width = Math.round(Math.abs((_local_10.x - _local_12.x)));
|
if(this._planeTexture.width !== this._width || this._planeTexture.height !== this._height)
|
||||||
height = Math.round(Math.abs((_local_10.x - _local_11.x)));
|
{
|
||||||
|
this._planeTexture.destroy(true);
|
||||||
|
|
||||||
const _local_15 = (_local_10.x - RoomPlane.PLANE_GEOMETRY.getScreenPoint(new Vector3d(1, 0, 0)).x);
|
this._planeTexture = null;
|
||||||
|
|
||||||
x = (this._textureOffsetX * Math.trunc(Math.abs(_local_15)));
|
|
||||||
y = (this._textureOffsetY * Math.trunc(Math.abs(_local_15)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if((x !== 0) || (y !== 0))
|
|
||||||
{
|
|
||||||
while(x < 0) x += texture.width;
|
|
||||||
|
|
||||||
while(y < 0) y += texture.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
planeSprite = new TilingSprite({
|
|
||||||
texture,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
tint: planeData.color,
|
|
||||||
tilePosition: {
|
|
||||||
x: (x % texture.width) + (this._textureOffsetX * texture.width),
|
|
||||||
y: (y % texture.height) + (this._textureOffsetY * texture.height)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RoomPlane.TYPE_WALL: {
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
width = Math.round(Math.abs((_local_8.x - _local_10.x)));
|
|
||||||
height = Math.round(Math.abs((_local_8.y - _local_9.y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
planeSprite = new TilingSprite({
|
|
||||||
texture,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
tint: planeData.color,
|
|
||||||
tilePosition: {
|
|
||||||
x: (this._textureOffsetX * texture.width),
|
|
||||||
y: (this._textureOffsetY * texture.height)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RoomPlane.TYPE_LANDSCAPE: {
|
|
||||||
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) / 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)));
|
|
||||||
const renderMaxY = Math.trunc(this._textureMaxY * Math.abs((_local_13.y - _local_14.y)));
|
|
||||||
|
|
||||||
const renderOffsetX = Math.trunc(this._textureOffsetX * Math.abs((_local_13.x - _local_15.x)));
|
|
||||||
const renderOffsetY = Math.trunc(this._textureOffsetY * Math.abs((_local_13.y - _local_14.y)));
|
|
||||||
|
|
||||||
planeSprite = new TilingSprite({
|
|
||||||
texture,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
tilePosition: {
|
|
||||||
x: renderOffsetX,
|
|
||||||
y: renderOffsetY
|
|
||||||
},
|
|
||||||
tint: planeData.color,
|
|
||||||
applyAnchorToTexture: true
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
planeSprite = new TilingSprite({
|
|
||||||
texture: Texture.WHITE,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
applyAnchorToTexture: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateMask(planeSprite, geometry);
|
if(!this._planeTexture) this._planeTexture = TextureUtils.createRenderTexture(this._width, this._height);
|
||||||
|
|
||||||
this._planeTexture = TextureUtils.createAndWriteRenderTexture(this._width, this._height, planeSprite, this.getMatrixForDimensions(width, height)) as Texture;
|
if(geometryChanged || maskChanged)
|
||||||
|
{
|
||||||
|
GetRenderer().render({
|
||||||
|
target: this._planeTexture,
|
||||||
|
container: this._planeSprite,
|
||||||
|
clear: true,
|
||||||
|
transform: this.getMatrixForDimensions(this._planeSprite.width, this._planeSprite.height)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -483,82 +528,73 @@ export class RoomPlane implements IRoomPlane
|
|||||||
if(maskChanged) this._maskChanged = false;
|
if(maskChanged) this._maskChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateMask(sprite: Container, geometry: IRoomGeometry): void
|
private updateMask(container: Container, geometry: IRoomGeometry): void
|
||||||
{
|
{
|
||||||
if(!sprite || !geometry) return;
|
if(!container || !geometry || !this._useMask || (!this._bitmapMasks.length && !this._rectangleMasks.length) || !this._maskManager) return;
|
||||||
|
|
||||||
if(!this._useMask || ((!this._bitmapMasks.length && !this._rectangleMasks.length) && !this._maskChanged) || !this._maskManager) return;
|
|
||||||
|
|
||||||
this.updateMaskChangeStatus();
|
this.updateMaskChangeStatus();
|
||||||
|
|
||||||
/* if(!this._maskBitmapData || (this._maskBitmapData.width !== width) || (this._maskBitmapData.height !== height))
|
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)
|
||||||
{
|
{
|
||||||
this._maskBitmapData = this._textureCache.createAndFillRenderTexture(width, height, 'mask');
|
const mask = this._bitmapMasks[i];
|
||||||
this._maskChanged = true;
|
|
||||||
} */
|
|
||||||
|
|
||||||
if(this._maskChanged)
|
if(mask)
|
||||||
{
|
|
||||||
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];
|
type = mask.type;
|
||||||
|
posX = (container.width - ((container.width * mask.leftSideLoc) / this._leftSide.length));
|
||||||
|
posY = (container.height - ((container.height * mask.rightSideLoc) / this._rightSide.length));
|
||||||
|
|
||||||
if(mask)
|
this._maskManager.addMaskToContainer(container, type, geometry.scale, normal, posX, posY);
|
||||||
{
|
this._bitmapMasksOld.push(new RoomPlaneBitmapMask(type, mask.leftSideLoc, mask.rightSideLoc));
|
||||||
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;
|
i++;
|
||||||
|
|
||||||
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);
|
i = 0;
|
||||||
|
|
||||||
|
while(i < this._rectangleMasks.length)
|
||||||
|
{
|
||||||
|
const rectMask = this._rectangleMasks[i];
|
||||||
|
|
||||||
|
if(rectMask)
|
||||||
|
{
|
||||||
|
posX = (container.width - ((container.width * rectMask.leftSideLoc) / this._leftSide.length));
|
||||||
|
posY = (container.height - ((container.height * rectMask.rightSideLoc) / this._rightSide.length));
|
||||||
|
|
||||||
|
const wd = ((container.width * rectMask.leftSideLength) / this._leftSide.length);
|
||||||
|
const ht = ((container.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));
|
||||||
|
|
||||||
|
container.addChild(maskSprite);
|
||||||
|
|
||||||
|
this._rectangleMasksOld.push(new RoomPlaneRectangleMask(rectMask.leftSideLength, rectMask.rightSideLoc, rectMask.leftSideLength, rectMask.rightSideLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._maskChanged = false;
|
||||||
|
|
||||||
|
container.filterArea = container.getBounds().rectangle;
|
||||||
|
|
||||||
|
container.filters = [ new PlaneMaskFilter({}) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
public get canBeVisible(): boolean
|
public get canBeVisible(): boolean
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IAssetPlaneMaskData, IAssetPlaneTextureBitmap, IGraphicAssetCollection, IVector3D } from '@nitrots/api';
|
import { IAssetPlaneMaskData, IAssetPlaneTextureBitmap, IGraphicAssetCollection, IVector3D } from '@nitrots/api';
|
||||||
import { CutMaskFilter } from '@nitrots/utils';
|
import { GetRenderer } from '@nitrots/utils';
|
||||||
import { Container, Matrix, Point } from 'pixi.js';
|
import { Container, Matrix, Point, Sprite, Texture } from 'pixi.js';
|
||||||
import { PlaneMask } from './PlaneMask';
|
import { PlaneMask } from './PlaneMask';
|
||||||
import { PlaneMaskVisualization } from './PlaneMaskVisualization';
|
import { PlaneMaskVisualization } from './PlaneMaskVisualization';
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ export class PlaneMaskManager
|
|||||||
return graphicName;
|
return graphicName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateMask(sprite: Container, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean
|
public addMaskToContainer(container: Container, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean
|
||||||
{
|
{
|
||||||
const mask = this._masks.get(type);
|
const mask = this._masks.get(type);
|
||||||
|
|
||||||
@ -157,14 +157,6 @@ export class PlaneMaskManager
|
|||||||
|
|
||||||
const point = new Point((posX + asset.offsetX), (posY + asset.offsetY));
|
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();
|
const matrix = new Matrix();
|
||||||
|
|
||||||
let xScale = 1;
|
let xScale = 1;
|
||||||
@ -193,7 +185,65 @@ export class PlaneMaskManager
|
|||||||
matrix.scale(xScale, ySkew);
|
matrix.scale(xScale, ySkew);
|
||||||
matrix.translate(tx, ty);
|
matrix.translate(tx, ty);
|
||||||
|
|
||||||
//TextureUtils.writeToTexture(new Sprite(texture), canvas, false, matrix);
|
const sprite = new Sprite(texture);
|
||||||
|
|
||||||
|
sprite.setFromMatrix(matrix);
|
||||||
|
|
||||||
|
container.addChild(sprite);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeMaskToTexture(targetTexture: Texture, type: string, scale: number, normal: IVector3D, posX: number, posY: number): boolean
|
||||||
|
{
|
||||||
|
const mask = this._masks.get(type);
|
||||||
|
|
||||||
|
if(!mask) return true;
|
||||||
|
|
||||||
|
const asset = mask.getGraphicAsset(scale, normal);
|
||||||
|
|
||||||
|
if(!asset) return true;
|
||||||
|
|
||||||
|
const texture = asset.texture;
|
||||||
|
|
||||||
|
if(!texture) return true;
|
||||||
|
|
||||||
|
const point = new Point((posX + asset.offsetX), (posY + asset.offsetY));
|
||||||
|
|
||||||
|
const matrix = new Matrix();
|
||||||
|
|
||||||
|
let xScale = 1;
|
||||||
|
let ySkew = 1;
|
||||||
|
let xSkew = 0;
|
||||||
|
let yScale = 0;
|
||||||
|
let tx = (point.x + xSkew);
|
||||||
|
let ty = (point.y + yScale);
|
||||||
|
|
||||||
|
if(asset.flipH)
|
||||||
|
{
|
||||||
|
xScale = -1;
|
||||||
|
xSkew = texture.width;
|
||||||
|
|
||||||
|
tx = ((point.x + xSkew) - texture.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(asset.flipV)
|
||||||
|
{
|
||||||
|
ySkew = -1;
|
||||||
|
yScale = texture.height;
|
||||||
|
|
||||||
|
ty = ((point.y + yScale) - texture.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix.scale(xScale, ySkew);
|
||||||
|
matrix.translate(tx, ty);
|
||||||
|
|
||||||
|
GetRenderer().render({
|
||||||
|
target: targetTexture,
|
||||||
|
container: new Sprite(texture),
|
||||||
|
clear: false,
|
||||||
|
transform: matrix
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,20 @@
|
|||||||
import { Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js';
|
import { Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js';
|
||||||
|
|
||||||
export interface CutTransparentAreaFilterOptions
|
export interface PlaneMaskFilterOptions
|
||||||
{
|
{
|
||||||
maskTexture: Texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CutMaskFilter extends Filter
|
export class PlaneMaskFilter extends Filter
|
||||||
{
|
{
|
||||||
public static readonly DEFAULT_OPTIONS: CutTransparentAreaFilterOptions = {
|
public static readonly DEFAULT_OPTIONS: PlaneMaskFilterOptions = {
|
||||||
maskTexture: Texture.WHITE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public uniforms: {
|
public uniforms: {
|
||||||
uColor: Float32Array;
|
|
||||||
uAlpha: number;
|
|
||||||
uDimensions: Float32Array;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(options: CutTransparentAreaFilterOptions)
|
constructor(options: PlaneMaskFilterOptions)
|
||||||
{
|
{
|
||||||
options = { ...CutMaskFilter.DEFAULT_OPTIONS, ...options };
|
options = { ...PlaneMaskFilter.DEFAULT_OPTIONS, ...options };
|
||||||
|
|
||||||
if(!options.maskTexture) throw Error('No texture provided for mask filter');
|
|
||||||
|
|
||||||
const glProgram = GlProgram.from({
|
const glProgram = GlProgram.from({
|
||||||
vertex: `in vec2 aPosition;
|
vertex: `in vec2 aPosition;
|
||||||
@ -51,33 +44,36 @@ export class CutMaskFilter extends Filter
|
|||||||
gl_Position = filterVertexPosition();
|
gl_Position = filterVertexPosition();
|
||||||
vTextureCoord = filterTextureCoord();
|
vTextureCoord = filterTextureCoord();
|
||||||
}`,
|
}`,
|
||||||
fragment: `varying vec2 vTextureCoord;
|
fragment: `
|
||||||
|
in vec2 vTextureCoord;
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D uTexture;
|
||||||
|
|
||||||
uniform sampler2D uSampler; // The sprite's texture
|
|
||||||
uniform sampler2D maskTexture; // The mask texture
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 spriteColor = texture2D(uSampler, vTextureCoord);
|
vec4 c = texture(uTexture, vTextureCoord);
|
||||||
vec4 maskColor = texture2D(maskTexture, vTextureCoord);
|
|
||||||
|
if(c.r == 0.0 && c.g == 0.0 && c.b == 0.0) {
|
||||||
// Use mask alpha to determine the transparency
|
finalColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
float alpha = maskColor.a;
|
} else {
|
||||||
|
finalColor = c;
|
||||||
// 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: 'plane-mask-filter',
|
||||||
name: 'cut-mask-filter',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
super({
|
super({
|
||||||
gpuProgram: null,
|
gpuProgram: null,
|
||||||
glProgram,
|
glProgram,
|
||||||
resources: {
|
resources: {
|
||||||
maskTexture: options.maskTexture
|
planeMaskUniforms: {
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.uniforms = this.resources.planeMaskUniforms.uniforms;
|
||||||
|
|
||||||
Object.assign(this, options);
|
Object.assign(this, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +84,7 @@ export class CutMaskFilter extends Filter
|
|||||||
clearMode: boolean,
|
clearMode: boolean,
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
|
|
||||||
filterManager.applyFilter(this, input, output, clearMode);
|
filterManager.applyFilter(this, input, output, clearMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
export * from './CutMaskFilter';
|
export * from './PlaneMaskFilter';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user