- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
import { Conic } from './Conic';
import { Container } from '@pixi/display';
import { Point, Matrix, Transform } from '@pixi/math';
import { Renderer, Texture } from '@pixi/core';
import { ConicRenderer } from './ConicRenderer';
import mat3 from 'gl-mat3';
const tempMatrix = new Matrix();
/**
* Draws a segment of conic section represented by the equation _k_<sup>2</sup>- _lm = 0_, where k, l, m are lines.
*
* This display-object shades the inside/outside of a conic section within a mesh.
*
* A conic curve can be represented in the form: _k_<sup>2</sup> - _lm = 0_, where k, l, m are lines described in
* the form _ax + by + c = 0_. _l_ and _m_ are the tangents to the curve, and _k_ is a chord connecting the points
* of tangency.
*/
export class ConicDisplay extends Container
{
public shape: Conic;
public vertexData: Array<number>;
public uvData: Array<number>;
public indexData: Array<number>;
protected _texture: Texture;
protected _updateID: number;
protected _transformID: number;
protected _dirtyID: number;
constructor(conic = new Conic(), texture: Texture)
{
super();
/**
* The conic curve drawn by this graphic.
*/
this.shape = conic;
/**
* Flags whether the geometry data needs to be updated.
*/
this._dirtyID = 0;
/**
* The world transform ID last when the geometry was updated.
*/
this._transformID = 0;
/**
* Last {@link _dirtyID} when the geometry was updated.
*/
this._updateID = -1;
/**
* World positions of the vertices
*/
this.vertexData = [];
/**
* Texture positions of the vertices.
*/
this.uvData = [];
this._texture = texture || Texture.WHITE;
}
/**
* @see Conic#k
*/
get k(): [number, number, number]
{
return this.shape.k;
}
set k(line: [number, number, number])
{
this.shape.setk(...line);
}
/**
* @see Conic#l
*/
get l(): [number, number, number]
{
return this.shape.l;
}
set l(line: [number, number, number])
{
this.shape.setl(...line);
}
/**
* @see Conic#m
*/
get m(): [number, number, number]
{
return this.shape.m;
}
set m(line: [number, number, number])
{
this.shape.setm(...line);
}
get texture(): Texture
{
return this._texture;
}
set texture(tex: Texture)
{
this._texture = tex || Texture.WHITE;
}
_calculateBounds(): void
{
this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length);
}
_render(renderer: Renderer): void
{
if (!renderer.plugins.conic)
{
renderer.plugins.conic = new ConicRenderer(renderer, null);
}
renderer.batch.setObjectRenderer(renderer.plugins.conic);
renderer.plugins.conic.render(this);
}
/**
* Draws the triangle formed by the control points of the shape.
*/
drawControlPoints(): this
{
const controlPoints = this.shape.controlPoints;
this.drawTriangle(
controlPoints[0].x, controlPoints[0].y,
controlPoints[1].x, controlPoints[1].y,
controlPoints[2].x, controlPoints[2].y,
);
return this;
}
/**
* Draw a triangle defined in texture space transformed into local space. Generally, you would want to draw the triangle
* formed by the shape's control points.
*
* @param x0
* @param y0
* @param x1
* @param y1
* @param x2
* @param y2
*/
drawTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): this
{
const data = this.uvData;
const i = data.length;
data.length += 6;
data[i] = x0;
data[i + 1] = y0;
data[i + 2] = x1;
data[i + 3] = y1;
data[i + 4] = x2;
data[i + 5] = y2;
return this;
}
/**
* @param x
* @param y
* @param width
* @param height
*/
drawRect(x: number, y: number, width: number, height: number): this
{
const data = this.uvData;
const i = data.length;
data.length += 12;
data[i] = x;
data[i + 1] = y;
data[i + 2] = x + width;
data[i + 3] = y;
data[i + 4] = x + width;
data[i + 5] = y + height;
data[i + 6] = x;
data[i + 7] = y;
data[i + 8] = x + width;
data[i + 9] = y + height;
data[i + 10] = x;
data[i + 11] = y + height;
return this;
}
/**
* Updates the geometry data for this conic.
*/
updateConic(): void
{
const vertexData = this.vertexData;
const uvData = this.uvData;
vertexData.length = uvData.length;
const matrix = tempMatrix.copyFrom(this.worldTransform);
const { a, b, c, d, tx, ty } = matrix;
for (let i = 0, j = vertexData.length / 2; i < j; i++)
{
const x = uvData[(i * 2)];
const y = uvData[(i * 2) + 1];
vertexData[(i * 2)] = (a * x) + (c * y) + tx;
vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty;
}
this._updateID = this._dirtyID;
const indexData = this.indexData = new Array(vertexData.length / 2);
// TODO: Remove indexData, pixi-batch-renderer might have a problem with it
for (let i = 0, j = indexData.length; i < j; i++)
{
indexData[i] = i;
}
}
/**
* Sets the local-space control points of the curve.
* @param c0
* @param c1
* @param c2
*/
setControlPoints(c0: Point, c1: Point, c2: Point): void
{
const texturePoints = this.shape.controlPoints;
this.setTransform(texturePoints[0], texturePoints[1], texturePoints[2],
c0, c1, c2);
}
/**
* Set the transform of the conic
*
* @param matrix - transformation between design space and texture space
*/
setTransform(matrix: Matrix): this;
/**
* Set the transformation by defining a triangle in design space _(a0, b0, c0)_ mapping to
* the triangle _(a1, b1, c1)_ in texture space.
*
* @param a0
* @param b0
* @param c0
* @param a1
* @param b1
* @param c1
*/
setTransform(a0: Point, b0: Point, c0: Point, a1: Point, b1: Point, c1: Point): this;
/**
* Set the transformation by defining the triangle in design space _(ax0, ay0), (bx0, by0), (cx0, cy0)_
* mapping to the triangle _(ax1, ay1), (bx1, by1), (cx1, cy1)_ in texture space.
*
* @param ax0
* @param ay0
* @param bx0
* @param by0
* @param cx0
* @param cy0
* @param ax1
* @param ay1
* @param bx1
* @param by1
* @param cx1
* @param cy1
*/
setTransform(ax0: number, ay0: number, bx0: number, by0: number, cx0: number, cy0: number,
ax1: number, ay1: number, bx1: number, by1: number, cx1: number, cy1: number): this;
setTransform(...args: any): this
{
const transform = this.transform;
const localTransform = transform.localTransform;
transform._localID++;
if (args.length === 1)
{
localTransform.copyFrom(args[0]);
return this;
}
if (args.length === 9)
{
super.setTransform(...args);
}
localTransform.identity();
// Design space
let ax0: number;
let ay0: number;
let bx0: number;
let by0: number;
let cx0: number;
let cy0: number;
// Texture space
let ax1: number;
let ay1: number;
let bx1: number;
let by1: number;
let cx1: number;
let cy1: number;
if (args.length === 6)
{
const points = args as Point[];
ax0 = points[0].x;
ay0 = points[0].y;
bx0 = points[1].x;
by0 = points[1].y;
cx0 = points[2].x;
cy0 = points[2].y;
ax1 = points[3].x;
ay1 = points[3].y;
bx1 = points[4].x;
by1 = points[4].y;
cx1 = points[5].x;
cy1 = points[5].y;
}
else
{
const coords = args as number[];
ax0 = coords[0];
ay0 = coords[1];
bx0 = coords[2];
by0 = coords[3];
cx0 = coords[4];
cy0 = coords[5];
ax1 = coords[6];
ay1 = coords[7];
bx1 = coords[8];
by1 = coords[9];
cx1 = coords[10];
cy1 = coords[11];
}
const input = [
ax0, bx0, cx0,
ay0, by0, cy0,
1, 1, 1,
];
const inverse = mat3.invert(input, input);
// input * textureTransform = output
// textureTransform = inverse(input) * output
localTransform.a = (inverse[0] * ax1) + (inverse[3] * bx1) + (inverse[6] * cx1);
localTransform.c = (inverse[1] * ax1) + (inverse[4] * bx1) + (inverse[7] * cx1);
localTransform.tx = (inverse[2] * ax1) + (inverse[5] * bx1) + (inverse[8] * cx1);
localTransform.b = (inverse[0] * ay1) + (inverse[3] * by1) + (inverse[6] * cy1);
localTransform.d = (inverse[1] * ay1) + (inverse[4] * by1) + (inverse[7] * cy1);
localTransform.ty = (inverse[2] * ay1) + (inverse[5] * by1) + (inverse[8] * cy1);
transform.setFromMatrix(localTransform);
return this;
}
/**
* Updates the transform of the conic, and if changed updates the geometry data.
*
* @override
*/
updateTransform(): void
{
const ret = super.updateTransform();
if (this._transformID !== this.transform._worldID)
{
this.updateConic();
this._transformID = this.transform._worldID;
}
return ret;
}
}