-
Notifications
You must be signed in to change notification settings - Fork 338
/
Mesh.hx
151 lines (125 loc) · 4.49 KB
/
Mesh.hx
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
package h3d.scene;
/**
h3d.scene.Mesh is the base class for all 3D objects displayed on screen.
Unlike Object base class, all properties of Mesh only apply to the current object and are not inherited by its children.
**/
class Mesh extends Object {
/**
The primitive of the mesh: the list of vertexes and indices necessary to display the mesh.
**/
public var primitive(default, set) : h3d.prim.Primitive;
/**
The material of the mesh: the properties used to display it (texture, color, shaders, etc.)
**/
public var material : h3d.mat.Material;
/**
When enabled, the lod level is inherited by children objects.
**/
public var inheritLod : Bool = false;
/**
Creates a new mesh with given primitive, material and parent object.
If material is not specified, a new default material is created for the current renderer.
**/
public function new( primitive, ?material, ?parent ) {
super(parent);
this.primitive = primitive;
if( material == null ) {
material = h3d.mat.MaterialSetup.current.createMaterial();
material.props = material.getDefaultProps();
}
this.material = material;
}
/**
Return all materials for the current object.
**/
public function getMeshMaterials() {
return [material];
}
static var tmpMat = new h3d.Matrix();
override function addBoundsRec( b : h3d.col.Bounds, relativeTo : h3d.Matrix ) {
super.addBoundsRec(b, relativeTo);
if( primitive == null || flags.has(FIgnoreBounds) )
return;
var bounds = primitive.getBounds();
if( relativeTo == null ) {
b.addTransform(bounds,absPos);
} else {
tmpMat.multiply(absPos, relativeTo);
b.addTransform(bounds,tmpMat);
}
}
override function clone( ?o : Object ) : Object {
var m = o == null ? new Mesh(null,material) : cast o;
m.primitive = primitive;
m.material = cast material.clone();
super.clone(m);
return m;
}
override function getLocalCollider() : h3d.col.Collider {
return primitive.getCollider();
}
var curScreenRatio : Float = 1.0;
override function draw( ctx : RenderContext ) {
primitive.selectMaterial(0, primitive.screenRatioToLod(curScreenRatio));
primitive.render(ctx.engine);
}
function calcScreenRatio( ctx : RenderContext ) {
if ( primitive == null || primitive.lodCount() == 1 )
return;
if ( ctx.forcedScreenRatio >= 0.0 ) {
curScreenRatio = ctx.forcedScreenRatio;
return;
}
var bounds = primitive.getBounds();
if ( bounds == null ) {
curScreenRatio = 1.0;
return;
}
var absPos = getAbsPos();
var worldCenter = absPos.getPosition();
var worldScale = absPos.getScale();
var worldRadius = bounds.dimension() * hxd.Math.max( worldScale.x, hxd.Math.max(worldScale.y, worldScale.z) ) / 2.0;
var cameraRight = ctx.camera.getRight();
var cameraUp = ctx.camera.getUp();
var cameraTopLeft = (cameraUp - cameraRight).normalized();
var worldTopLeft = worldCenter + cameraTopLeft * worldRadius;
var worldBottomRight = worldCenter - cameraTopLeft * worldRadius;
var screenTopLeft = ctx.camera.projectInline( worldTopLeft.x, worldTopLeft.y, worldTopLeft.z, 1.0, 1.0, false );
var screenBottomRight = ctx.camera.projectInline( worldBottomRight.x, worldBottomRight.y, worldBottomRight.z, 1.0, 1.0, false );
var screenArea = hxd.Math.max( screenBottomRight.x - screenTopLeft.x, screenBottomRight.y - screenTopLeft.y );
curScreenRatio = screenArea * screenArea;
if ( inheritLod )
ctx.forcedScreenRatio = curScreenRatio;
}
override function emit( ctx : RenderContext ) {
calcScreenRatio(ctx);
ctx.emit(material, this);
}
override function getMaterialByName( name : String ) : h3d.mat.Material {
if( material != null && material.name == name )
return material;
return super.getMaterialByName(name);
}
override function getMaterials( ?a : Array<h3d.mat.Material>, recursive = true ) {
if( a == null ) a = [];
if( material != null && a.indexOf(material) < 0 ) a.push(material);
return super.getMaterials(a, recursive);
}
override private function onAdd()
{
super.onAdd();
if ( primitive != null ) primitive.incref();
}
override private function onRemove()
{
if ( primitive != null ) primitive.decref();
super.onRemove();
}
function set_primitive( prim : h3d.prim.Primitive ) : h3d.prim.Primitive {
if ( prim != this.primitive && allocated ) {
if (this.primitive != null) this.primitive.decref();
if (prim != null) prim.incref();
}
return this.primitive = prim;
}
}