[update] Tidied codes of elements.
This commit is contained in:
parent
a39c9f5001
commit
f5500b0b98
31
sjplayer/src/sjplayer/AbstractShapeElement.d
Normal file
31
sjplayer/src/sjplayer/AbstractShapeElement.d
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/// License: MIT
|
||||||
|
module sjplayer.AbstractShapeElement;
|
||||||
|
|
||||||
|
import gl4d;
|
||||||
|
|
||||||
|
import sjplayer.ElementInterface,
|
||||||
|
sjplayer.ShapeElementProgram;
|
||||||
|
|
||||||
|
///
|
||||||
|
abstract class AbstractShapeElement : ElementInterface {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
void Initialize() {
|
||||||
|
alive = false;
|
||||||
|
damage = 0;
|
||||||
|
nearness_coe = 0;
|
||||||
|
instance = instance.init;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const;
|
||||||
|
|
||||||
|
///
|
||||||
|
bool alive;
|
||||||
|
///
|
||||||
|
float damage;
|
||||||
|
///
|
||||||
|
float nearness_coe;
|
||||||
|
///
|
||||||
|
ShapeElementProgramInstance instance;
|
||||||
|
alias instance this;
|
||||||
|
}
|
@ -6,22 +6,16 @@ import std.algorithm,
|
|||||||
|
|
||||||
import gl4d;
|
import gl4d;
|
||||||
|
|
||||||
import sjplayer.ElementDrawer,
|
import sjplayer.AbstractShapeElement,
|
||||||
sjplayer.ElementInterface,
|
sjplayer.ElementInterface,
|
||||||
|
sjplayer.ShapeElementDrawer,
|
||||||
sjplayer.ShapeElementProgram,
|
sjplayer.ShapeElementProgram,
|
||||||
|
sjplayer.ShapeElementScheduledController,
|
||||||
sjplayer.util.linalg;
|
sjplayer.util.linalg;
|
||||||
|
|
||||||
///
|
///
|
||||||
class CircleElement : ElementInterface {
|
class CircleElement : AbstractShapeElement {
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
void Initialize() {
|
|
||||||
alive = false;
|
|
||||||
damage = 0;
|
|
||||||
nearness_coe = 0;
|
|
||||||
instance = instance.init;
|
|
||||||
}
|
|
||||||
|
|
||||||
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
||||||
if (!alive) return DamageCalculationResult(0, 0);
|
if (!alive) return DamageCalculationResult(0, 0);
|
||||||
|
|
||||||
@ -35,22 +29,11 @@ class CircleElement : ElementInterface {
|
|||||||
}
|
}
|
||||||
return DamageCalculationResult(0, 1 - (d-1).clamp(0, 1));
|
return DamageCalculationResult(0, 1 - (d-1).clamp(0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
bool alive;
|
|
||||||
///
|
|
||||||
float damage;
|
|
||||||
///
|
|
||||||
float nearness_coe;
|
|
||||||
///
|
|
||||||
CircleElementProgram.Instance instance;
|
|
||||||
alias instance this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
alias CircleElementDrawer = ElementDrawer!(
|
alias CircleElementDrawer = ShapeElementDrawer!(
|
||||||
CircleElementProgram,
|
CircleElementProgram,
|
||||||
CircleElement,
|
|
||||||
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
|
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -61,3 +44,9 @@ alias CircleElementProgram = ShapeElementProgram!(q{
|
|||||||
smoothstep(w-smooth_, w, r) *
|
smoothstep(w-smooth_, w, r) *
|
||||||
(1 - smoothstep(1-smooth_, 1, r));
|
(1 - smoothstep(1-smooth_, 1, r));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
alias CircleElementScheduledControllerFactory =
|
||||||
|
ShapeElementScheduledControllerFactory!(
|
||||||
|
CircleElement,
|
||||||
|
CircleElementDrawer);
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
/// License: MIT
|
|
||||||
module sjplayer.CircleElementScheduledController;
|
|
||||||
|
|
||||||
import sjplayer.CircleElement,
|
|
||||||
sjplayer.ElementScheduledControllerFactory,
|
|
||||||
sjplayer.ScheduledController,
|
|
||||||
sjplayer.ShapeElementScheduledController;
|
|
||||||
|
|
||||||
///
|
|
||||||
alias CircleElementScheduledController =
|
|
||||||
ShapeElementScheduledController!CircleElement;
|
|
||||||
|
|
||||||
///
|
|
||||||
alias CircleElementScheduledControllerFactory =
|
|
||||||
ElementScheduledControllerFactory!(
|
|
||||||
CircleElementScheduledController,
|
|
||||||
CircleElementDrawer);
|
|
@ -21,7 +21,6 @@ import sjplayer.Actor,
|
|||||||
sjplayer.PostEffectControllerInterface,
|
sjplayer.PostEffectControllerInterface,
|
||||||
sjplayer.ProgramSet,
|
sjplayer.ProgramSet,
|
||||||
sjplayer.ScheduledControllerInterface,
|
sjplayer.ScheduledControllerInterface,
|
||||||
sjplayer.SquareElementScheduledController,
|
|
||||||
sjplayer.VarStore,
|
sjplayer.VarStore,
|
||||||
sjplayer.VarStoreScheduledController;
|
sjplayer.VarStoreScheduledController;
|
||||||
|
|
||||||
@ -38,7 +37,8 @@ class Context {
|
|||||||
auto varstore = new VarStore(actor_);
|
auto varstore = new VarStore(actor_);
|
||||||
|
|
||||||
import sjplayer.BackgroundScheduledController,
|
import sjplayer.BackgroundScheduledController,
|
||||||
sjplayer.CircleElementScheduledController;
|
sjplayer.CircleElement,
|
||||||
|
sjplayer.SquareElement;
|
||||||
auto factories = tuple(
|
auto factories = tuple(
|
||||||
tuple(
|
tuple(
|
||||||
"actor",
|
"actor",
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
/// License: MIT
|
|
||||||
module sjplayer.ElementScheduledControllerFactory;
|
|
||||||
|
|
||||||
import sjscript;
|
|
||||||
|
|
||||||
import std.algorithm,
|
|
||||||
std.array,
|
|
||||||
std.conv,
|
|
||||||
std.meta,
|
|
||||||
std.range.primitives,
|
|
||||||
std.traits;
|
|
||||||
|
|
||||||
import sjplayer.ContextBuilderInterface,
|
|
||||||
sjplayer.ElementDrawerInterface,
|
|
||||||
sjplayer.ElementInterface,
|
|
||||||
sjplayer.ProgramSet,
|
|
||||||
sjplayer.ScheduledControllerInterface,
|
|
||||||
sjplayer.VarStoreInterface,
|
|
||||||
sjplayer.util.Period;
|
|
||||||
|
|
||||||
///
|
|
||||||
struct ElementScheduledControllerFactory(ScheduledController, ElementDrawer)
|
|
||||||
if (is(ScheduledController : ScheduledControllerInterface) &&
|
|
||||||
is(ElementDrawer : ElementDrawerInterface)) {
|
|
||||||
public:
|
|
||||||
/// ScheduledController's first constructor's first argument type.
|
|
||||||
alias Element =
|
|
||||||
Parameters!(__traits(getOverloads, ScheduledController, "__ctor")[0])[0];
|
|
||||||
|
|
||||||
static assert(is(Element : ElementInterface));
|
|
||||||
|
|
||||||
/// ElementDrawer's first constructor's first argument type.
|
|
||||||
alias ElementProgram =
|
|
||||||
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[0];
|
|
||||||
|
|
||||||
static assert(staticIndexOf!(
|
|
||||||
ElementProgram, ProgramSet.Programs.Types) >= 0);
|
|
||||||
static assert(is(Element[] :
|
|
||||||
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[1]));
|
|
||||||
|
|
||||||
///
|
|
||||||
this(ProgramSet programs, VarStoreInterface varstore) {
|
|
||||||
program_ = programs.Get!ElementProgram;
|
|
||||||
varstore_ = varstore;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
void Create(R)(R params, ContextBuilderInterface builder)
|
|
||||||
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
|
|
||||||
auto parallelized = ParallelizeParams(params);
|
|
||||||
auto elements = appender!(Element[]);
|
|
||||||
|
|
||||||
foreach (ref serial; parallelized) {
|
|
||||||
auto element = new Element;
|
|
||||||
elements ~= element;
|
|
||||||
builder.AddElement(element);
|
|
||||||
builder.AddScheduledController(
|
|
||||||
new ScheduledController(element, varstore_, serial));
|
|
||||||
}
|
|
||||||
if (elements[].length > 0) {
|
|
||||||
builder.AddElementDrawer(new ElementDrawer(program_, elements[]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static ParametersBlock[][] ParallelizeParams(R)(R params)
|
|
||||||
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
|
|
||||||
ParametersBlock[][] parallelized;
|
|
||||||
foreach (ref param; params) {
|
|
||||||
auto inserted = false;
|
|
||||||
foreach (ref serial; parallelized) {
|
|
||||||
const found_index = serial.
|
|
||||||
countUntil!(x => x.period.start > param.period.start);
|
|
||||||
const insert_index =
|
|
||||||
found_index >= 0? found_index.to!size_t: serial.length;
|
|
||||||
|
|
||||||
const intersect_prev = insert_index >= 1 &&
|
|
||||||
IsPeriodIntersectedToPeriod(serial[insert_index-1].period, param.period);
|
|
||||||
const intersect_next = insert_index < serial.length &&
|
|
||||||
IsPeriodIntersectedToPeriod(serial[insert_index].period, param.period);
|
|
||||||
|
|
||||||
if (!intersect_prev && !intersect_next) {
|
|
||||||
serial = serial[0..insert_index]~ param ~serial[insert_index..$];
|
|
||||||
inserted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!inserted) {
|
|
||||||
parallelized ~= [param];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parallelized;
|
|
||||||
}
|
|
||||||
|
|
||||||
ElementProgram program_;
|
|
||||||
|
|
||||||
VarStoreInterface varstore_;
|
|
||||||
}
|
|
@ -1,15 +1,13 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sjplayer.ScheduledController;
|
module sjplayer.ScheduledController;
|
||||||
|
|
||||||
import std.traits,
|
import std.typecons;
|
||||||
std.typecons;
|
|
||||||
|
|
||||||
import gl4d;
|
import gl4d;
|
||||||
|
|
||||||
import sjscript;
|
import sjscript;
|
||||||
|
|
||||||
import sjplayer.AbstractScheduledController,
|
import sjplayer.AbstractScheduledController,
|
||||||
sjplayer.ScheduledControllerInterface,
|
|
||||||
sjplayer.VarStoreInterface,
|
sjplayer.VarStoreInterface,
|
||||||
sjplayer.util.Parameter;
|
sjplayer.util.Parameter;
|
||||||
|
|
||||||
@ -17,18 +15,6 @@ import sjplayer.AbstractScheduledController,
|
|||||||
class ScheduledController(
|
class ScheduledController(
|
||||||
Target, string[string] ParameterNameMap) : AbstractScheduledController {
|
Target, string[string] ParameterNameMap) : AbstractScheduledController {
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
enum AliveManagementAvailable =
|
|
||||||
is(typeof((Target x) => x.alive)) &&
|
|
||||||
is(ReturnType!((Target x) => x.alive) == bool);
|
|
||||||
///
|
|
||||||
enum MatrixModificationAvailable =
|
|
||||||
is(typeof((Target x) => x.matrix)) &&
|
|
||||||
is(ReturnType!((Target x) => x.matrix) == mat3);
|
|
||||||
///
|
|
||||||
enum AutoInitializationAvailable =
|
|
||||||
is(typeof((Target x) => x.Initialize()));
|
|
||||||
|
|
||||||
///
|
///
|
||||||
this(
|
this(
|
||||||
Target target,
|
Target target,
|
||||||
@ -39,30 +25,6 @@ class ScheduledController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
override void PrepareOperation(ref in ParametersBlock params) {
|
|
||||||
static if (AutoInitializationAvailable) {
|
|
||||||
target_.Initialize();
|
|
||||||
}
|
|
||||||
static if (AliveManagementAvailable) {
|
|
||||||
target_.alive = true;
|
|
||||||
}
|
|
||||||
static if (MatrixModificationAvailable) {
|
|
||||||
matrix_factory_ = matrix_factory_.init;
|
|
||||||
}
|
|
||||||
super.PrepareOperation(params);
|
|
||||||
}
|
|
||||||
override void ProcessOperation(float time, ref in ParametersBlock params) {
|
|
||||||
super.ProcessOperation(time, params);
|
|
||||||
static if (MatrixModificationAvailable) {
|
|
||||||
target_.matrix = matrix_factory_.Create();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override void FinalizeOperation(ref in ParametersBlock params) {
|
|
||||||
static if (AliveManagementAvailable) {
|
|
||||||
target_.alive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override Nullable!float GetVariable(string name) const {
|
override Nullable!float GetVariable(string name) const {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
static foreach (map_name, code; ParameterNameMap) {
|
static foreach (map_name, code; ParameterNameMap) {
|
||||||
@ -71,10 +33,6 @@ class ScheduledController(
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
static if (MatrixModificationAvailable) {
|
|
||||||
const value = matrix_factory_.GetModelMatrixParameterValueByName(name);
|
|
||||||
if (!value.isNull) return value;
|
|
||||||
}
|
|
||||||
return super.GetVariable(name);
|
return super.GetVariable(name);
|
||||||
}
|
}
|
||||||
override void SetParameter(ref in Parameter param, ref in VarStore vars) {
|
override void SetParameter(ref in Parameter param, ref in VarStore vars) {
|
||||||
@ -86,15 +44,8 @@ class ScheduledController(
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
static if (MatrixModificationAvailable) {
|
|
||||||
if (param.CalculateModelMatrixParameter(matrix_factory_, vars)) return;
|
|
||||||
}
|
|
||||||
super.SetParameter(param, vars);
|
super.SetParameter(param, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Target target_;
|
Target target_;
|
||||||
|
|
||||||
static if (MatrixModificationAvailable) {
|
|
||||||
ModelMatrixFactory!3 matrix_factory_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sjplayer.ElementDrawer;
|
module sjplayer.ShapeElementDrawer;
|
||||||
|
|
||||||
import std.algorithm,
|
import std.algorithm,
|
||||||
std.conv;
|
std.conv,
|
||||||
|
std.exception;
|
||||||
|
|
||||||
import gl4d;
|
import gl4d;
|
||||||
|
|
||||||
import sjplayer.ElementDrawerInterface;
|
import sjplayer.AbstractShapeElement,
|
||||||
|
sjplayer.ElementDrawerInterface,
|
||||||
|
sjplayer.ShapeElementProgram;
|
||||||
|
|
||||||
///
|
///
|
||||||
class ElementDrawer(Program, Element, vec2[] vertices) :
|
class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
||||||
ElementDrawerInterface {
|
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
alias Instance = typeof(Element.instance);
|
enum MaxInstanceCount = 512;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(Program program, in Element[] elements)
|
this(Program program, in AbstractShapeElement[] shapes)
|
||||||
in (program)
|
in (program)
|
||||||
in (elements.length > 0) {
|
in (shapes.length > 0) {
|
||||||
program_ = program;
|
program_ = program;
|
||||||
elements_ = elements;
|
shapes_ = shapes;
|
||||||
|
|
||||||
vao_ = VertexArray.Create();
|
vao_ = VertexArray.Create();
|
||||||
verts_ = ArrayBuffer.Create();
|
verts_ = ArrayBuffer.Create();
|
||||||
@ -41,7 +43,7 @@ class ElementDrawer(Program, Element, vec2[] vertices) :
|
|||||||
|
|
||||||
instances_.Bind();
|
instances_.Bind();
|
||||||
with (ArrayBufferAllocator()) {
|
with (ArrayBufferAllocator()) {
|
||||||
size = Instance.sizeof * elements.length;
|
size = ShapeElementProgramInstance.sizeof * MaxInstanceCount;
|
||||||
usage = GL_DYNAMIC_DRAW;
|
usage = GL_DYNAMIC_DRAW;
|
||||||
Allocate(instances_);
|
Allocate(instances_);
|
||||||
}
|
}
|
||||||
@ -52,9 +54,10 @@ class ElementDrawer(Program, Element, vec2[] vertices) :
|
|||||||
|
|
||||||
instances_.Bind();
|
instances_.Bind();
|
||||||
{
|
{
|
||||||
auto ptr = instances_.MapToWrite!Instance();
|
auto ptr = instances_.MapToWrite!ShapeElementProgramInstance();
|
||||||
foreach (const element; elements_.filter!"a.alive") {
|
foreach (const shape; shapes_.filter!"a.alive") {
|
||||||
ptr[alive_count++] = element.instance;
|
enforce(alive_count <= MaxInstanceCount);
|
||||||
|
ptr[alive_count++] = shape.instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +72,7 @@ class ElementDrawer(Program, Element, vec2[] vertices) :
|
|||||||
private:
|
private:
|
||||||
Program program_;
|
Program program_;
|
||||||
|
|
||||||
const Element[] elements_;
|
const AbstractShapeElement[] shapes_;
|
||||||
|
|
||||||
ArrayBufferRef verts_;
|
ArrayBufferRef verts_;
|
||||||
ArrayBufferRef instances_;
|
ArrayBufferRef instances_;
|
@ -8,18 +8,6 @@ import gl4d;
|
|||||||
///
|
///
|
||||||
class ShapeElementProgram(string ShaderSrc) {
|
class ShapeElementProgram(string ShaderSrc) {
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
static struct Instance {
|
|
||||||
///
|
|
||||||
align(1) mat3 matrix = mat3.identity;
|
|
||||||
///
|
|
||||||
align(1) float weight = 1;
|
|
||||||
///
|
|
||||||
align(1) float smooth = 0.001;
|
|
||||||
///
|
|
||||||
align(1) vec4 color = vec4(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
enum ShaderHeader = "#version 330 core
|
enum ShaderHeader = "#version 330 core
|
||||||
#extension GL_ARB_explicit_uniform_location : enable";
|
#extension GL_ARB_explicit_uniform_location : enable";
|
||||||
@ -91,7 +79,7 @@ class ShapeElementProgram(string ShaderSrc) {
|
|||||||
|
|
||||||
type = GL_FLOAT;
|
type = GL_FLOAT;
|
||||||
divisor = 1;
|
divisor = 1;
|
||||||
stride = Instance.sizeof;
|
stride = ShapeElementProgramInstance.sizeof;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
// matrix
|
// matrix
|
||||||
@ -134,3 +122,16 @@ class ShapeElementProgram(string ShaderSrc) {
|
|||||||
private:
|
private:
|
||||||
ProgramRef program_;
|
ProgramRef program_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
struct ShapeElementProgramInstance {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
align(1) mat3 matrix = mat3.identity;
|
||||||
|
///
|
||||||
|
align(1) float weight = 1;
|
||||||
|
///
|
||||||
|
align(1) float smooth = 0.001;
|
||||||
|
///
|
||||||
|
align(1) vec4 color = vec4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
@ -1,28 +1,147 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sjplayer.ShapeElementScheduledController;
|
module sjplayer.ShapeElementScheduledController;
|
||||||
|
|
||||||
import sjplayer.CircleElement,
|
import std.algorithm,
|
||||||
sjplayer.ElementInterface,
|
std.array,
|
||||||
sjplayer.ElementScheduledControllerFactory,
|
std.conv,
|
||||||
sjplayer.ScheduledController;
|
std.range.primitives,
|
||||||
|
std.traits,
|
||||||
|
std.typecons;
|
||||||
|
|
||||||
|
import gl4d;
|
||||||
|
|
||||||
|
import sjscript;
|
||||||
|
|
||||||
|
import sjplayer.AbstractShapeElement,
|
||||||
|
sjplayer.ContextBuilderInterface,
|
||||||
|
sjplayer.ProgramSet,
|
||||||
|
sjplayer.ScheduledController,
|
||||||
|
sjplayer.ShapeElementScheduledController,
|
||||||
|
sjplayer.VarStoreInterface,
|
||||||
|
sjplayer.util.Parameter,
|
||||||
|
sjplayer.util.Period;
|
||||||
|
|
||||||
|
private enum NameMap = [
|
||||||
|
"damage": "damage",
|
||||||
|
"nearness_coe": "nearness_coe",
|
||||||
|
"weight": "weight",
|
||||||
|
"smooth": "smooth",
|
||||||
|
"color_r": "color.r",
|
||||||
|
"color_g": "color.g",
|
||||||
|
"color_b": "color.b",
|
||||||
|
"color_a": "color.a",
|
||||||
|
];
|
||||||
|
|
||||||
///
|
///
|
||||||
template ShapeElementScheduledController(Element)
|
class ShapeElementScheduledController :
|
||||||
if (is(Element : ElementInterface)) {
|
ScheduledController!(AbstractShapeElement, NameMap) {
|
||||||
alias ShapeElementScheduledController = ScheduledController!(
|
public:
|
||||||
Element,
|
///
|
||||||
[
|
this(
|
||||||
"damage": "damage",
|
AbstractShapeElement shape,
|
||||||
"nearness_coe": "nearness_coe",
|
in VarStoreInterface varstore,
|
||||||
"weight": "weight",
|
in ParametersBlock[] operations) {
|
||||||
"smooth": "smooth",
|
super(shape, varstore, operations);
|
||||||
"color_r": "color.r",
|
shape_ = shape;
|
||||||
"color_g": "color.g",
|
}
|
||||||
"color_b": "color.b",
|
|
||||||
"color_a": "color.a",
|
protected:
|
||||||
]
|
override void PrepareOperation(ref in ParametersBlock params) {
|
||||||
);
|
shape_.Initialize();
|
||||||
static assert(ShapeElementScheduledController.AliveManagementAvailable);
|
shape_.alive = true;
|
||||||
static assert(ShapeElementScheduledController.MatrixModificationAvailable);
|
|
||||||
static assert(ShapeElementScheduledController.AutoInitializationAvailable);
|
matrix_factory_ = matrix_factory_.init;
|
||||||
|
super.PrepareOperation(params);
|
||||||
|
}
|
||||||
|
override void ProcessOperation(float time, ref in ParametersBlock params) {
|
||||||
|
super.ProcessOperation(time, params);
|
||||||
|
shape_.matrix = matrix_factory_.Create();
|
||||||
|
}
|
||||||
|
override void FinalizeOperation(ref in ParametersBlock params) {
|
||||||
|
shape_.alive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
override Nullable!float GetVariable(string name) const {
|
||||||
|
const value = matrix_factory_.
|
||||||
|
GetModelMatrixParameterValueByName(name);
|
||||||
|
if (!value.isNull) return value;
|
||||||
|
|
||||||
|
return super.GetVariable(name);
|
||||||
|
}
|
||||||
|
override void SetParameter(ref in Parameter param, ref in VarStore vars) {
|
||||||
|
if (param.CalculateModelMatrixParameter(matrix_factory_, vars)) return;
|
||||||
|
super.SetParameter(param, vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractShapeElement shape_;
|
||||||
|
|
||||||
|
ModelMatrixFactory!3 matrix_factory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
struct ShapeElementScheduledControllerFactory(ShapeElement, ShapeElementDrawer)
|
||||||
|
if (is(ShapeElement : AbstractShapeElement)) {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
alias ShapeElementProgram =
|
||||||
|
Parameters!(__traits(getOverloads, ShapeElementDrawer, "__ctor")[0])[0];
|
||||||
|
|
||||||
|
///
|
||||||
|
this(ProgramSet programs, VarStoreInterface varstore) {
|
||||||
|
program_ = programs.Get!ShapeElementProgram;
|
||||||
|
varstore_ = varstore;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void Create(R)(R params, ContextBuilderInterface builder)
|
||||||
|
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
|
||||||
|
auto parallelized = ParallelizeParams(params);
|
||||||
|
auto elements = appender!(ShapeElement[]);
|
||||||
|
|
||||||
|
foreach (ref serial; parallelized) {
|
||||||
|
auto element = new ShapeElement;
|
||||||
|
elements ~= element;
|
||||||
|
builder.AddElement(element);
|
||||||
|
builder.AddScheduledController(
|
||||||
|
new ShapeElementScheduledController(element, varstore_, serial));
|
||||||
|
}
|
||||||
|
if (elements[].length > 0) {
|
||||||
|
builder.AddElementDrawer(new ShapeElementDrawer(program_, elements[]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ParametersBlock[][] ParallelizeParams(R)(R params)
|
||||||
|
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
|
||||||
|
ParametersBlock[][] parallelized;
|
||||||
|
foreach (ref param; params) {
|
||||||
|
auto inserted = false;
|
||||||
|
foreach (ref serial; parallelized) {
|
||||||
|
const found_index = serial.
|
||||||
|
countUntil!(x => x.period.start > param.period.start);
|
||||||
|
const insert_index =
|
||||||
|
found_index >= 0? found_index.to!size_t: serial.length;
|
||||||
|
|
||||||
|
const intersect_prev = insert_index >= 1 &&
|
||||||
|
IsPeriodIntersectedToPeriod(serial[insert_index-1].period, param.period);
|
||||||
|
const intersect_next = insert_index < serial.length &&
|
||||||
|
IsPeriodIntersectedToPeriod(serial[insert_index].period, param.period);
|
||||||
|
|
||||||
|
if (!intersect_prev && !intersect_next) {
|
||||||
|
serial = serial[0..insert_index]~ param ~serial[insert_index..$];
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inserted) {
|
||||||
|
parallelized ~= [param];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parallelized;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeElementProgram program_;
|
||||||
|
|
||||||
|
VarStoreInterface varstore_;
|
||||||
}
|
}
|
||||||
|
@ -6,34 +6,16 @@ import std.algorithm,
|
|||||||
|
|
||||||
import gl4d;
|
import gl4d;
|
||||||
|
|
||||||
import sjplayer.ElementDrawer,
|
import sjplayer.AbstractShapeElement,
|
||||||
sjplayer.ElementInterface,
|
sjplayer.ElementInterface,
|
||||||
|
sjplayer.ShapeElementDrawer,
|
||||||
|
sjplayer.ShapeElementScheduledController,
|
||||||
sjplayer.ShapeElementProgram,
|
sjplayer.ShapeElementProgram,
|
||||||
sjplayer.util.linalg;
|
sjplayer.util.linalg;
|
||||||
|
|
||||||
///
|
///
|
||||||
class SquareElement : ElementInterface {
|
class SquareElement : AbstractShapeElement {
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
static struct Instance {
|
|
||||||
///
|
|
||||||
align(1) mat3 matrix = mat3.identity;
|
|
||||||
///
|
|
||||||
align(1) float weight = 1;
|
|
||||||
///
|
|
||||||
align(1) float smooth = 0.001;
|
|
||||||
///
|
|
||||||
align(1) vec4 color = vec4(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
void Initialize() {
|
|
||||||
alive = false;
|
|
||||||
damage = 0;
|
|
||||||
nearness_coe = 0;
|
|
||||||
instance = instance.init;
|
|
||||||
}
|
|
||||||
|
|
||||||
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
||||||
if (!alive) return DamageCalculationResult(0, 0);
|
if (!alive) return DamageCalculationResult(0, 0);
|
||||||
|
|
||||||
@ -63,22 +45,11 @@ class SquareElement : ElementInterface {
|
|||||||
}
|
}
|
||||||
return DamageCalculationResult(0, 1-(min_distance-1).clamp(0f, 1f));
|
return DamageCalculationResult(0, 1-(min_distance-1).clamp(0f, 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
bool alive;
|
|
||||||
///
|
|
||||||
float damage;
|
|
||||||
///
|
|
||||||
float nearness_coe;
|
|
||||||
///
|
|
||||||
Instance instance;
|
|
||||||
alias instance this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
alias SquareElementDrawer = ElementDrawer!(
|
alias SquareElementDrawer = ShapeElementDrawer!(
|
||||||
SquareElementProgram,
|
SquareElementProgram,
|
||||||
SquareElement,
|
|
||||||
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
|
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -89,3 +60,9 @@ alias SquareElementProgram = ShapeElementProgram!(q{
|
|||||||
smoothstep(w-s, w, abs(uv_.x)) +
|
smoothstep(w-s, w, abs(uv_.x)) +
|
||||||
smoothstep(w-s, w, abs(uv_.y)), 0, 1);
|
smoothstep(w-s, w, abs(uv_.y)), 0, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
alias SquareElementScheduledControllerFactory =
|
||||||
|
ShapeElementScheduledControllerFactory!(
|
||||||
|
SquareElement,
|
||||||
|
SquareElementDrawer);
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
/// License: MIT
|
|
||||||
module sjplayer.SquareElementScheduledController;
|
|
||||||
|
|
||||||
import sjplayer.ElementScheduledControllerFactory,
|
|
||||||
sjplayer.ScheduledController,
|
|
||||||
sjplayer.ShapeElementScheduledController,
|
|
||||||
sjplayer.SquareElement;
|
|
||||||
|
|
||||||
///
|
|
||||||
alias SquareElementScheduledController =
|
|
||||||
ShapeElementScheduledController!SquareElement;
|
|
||||||
|
|
||||||
///
|
|
||||||
alias SquareElementScheduledControllerFactory =
|
|
||||||
ElementScheduledControllerFactory!(
|
|
||||||
SquareElementScheduledController,
|
|
||||||
SquareElementDrawer);
|
|
Reference in New Issue
Block a user