Revision 0f10a0b6
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/library/effect/EffectName.java | ||
---|---|---|
50 | 50 |
SHEAR ( EffectType.MATRIX , new float[] {0.0f,0.0f,0.0f} , 3, 0, 3 , MatrixEffectShear.class ), |
51 | 51 |
|
52 | 52 |
DISTORT ( EffectType.VERTEX , new float[] {0.0f,0.0f,0.0f} , 3, 4, 3 , VertexEffectDistort.class ), |
53 |
DEFORM ( EffectType.VERTEX , new float[] {0.0f,0.0f,0.0f} , 3, 4, 3 , VertexEffectDeform.class ),
|
|
53 |
DEFORM ( EffectType.VERTEX , new float[] {0.0f,0.0f,0.0f} , 4, 4, 3 , VertexEffectDeform.class ),
|
|
54 | 54 |
SINK ( EffectType.VERTEX , new float[] {1.0f} , 1, 4, 3 , VertexEffectSink.class ), |
55 | 55 |
PINCH ( EffectType.VERTEX , new float[] {1.0f} , 3, 4, 3 , VertexEffectPinch.class ), |
56 | 56 |
SWIRL ( EffectType.VERTEX , new float[] {0.0f} , 1, 4, 3 , VertexEffectSwirl.class ), |
src/main/java/org/distorted/library/effect/VertexEffectDeform.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
package org.distorted.library.effect; |
21 | 21 |
|
22 |
import org.distorted.library.type.Data1D; |
|
22 | 23 |
import org.distorted.library.type.Data3D; |
23 | 24 |
import org.distorted.library.type.Data4D; |
24 | 25 |
|
... | ... | |
29 | 30 |
public class VertexEffectDeform extends VertexEffect |
30 | 31 |
{ |
31 | 32 |
private Data3D mVector, mCenter; |
33 |
private Data1D mRadius; |
|
32 | 34 |
private Data4D mRegion; |
33 | 35 |
|
34 | 36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
41 | 43 |
{ |
42 | 44 |
mCenter.get(uniforms,index+CENTER_OFFSET,currentDuration,step); |
43 | 45 |
mRegion.get(uniforms,index+REGION_OFFSET,currentDuration,step); |
46 |
mRadius.get(uniforms,index+3,currentDuration,step); |
|
44 | 47 |
return mVector.get(uniforms,index,currentDuration,step); |
45 | 48 |
} |
46 | 49 |
|
... | ... | |
98 | 101 |
// along the force line is. |
99 | 102 |
// 0<=C<1 looks completely ridiculous and C<0 destroys the system. |
100 | 103 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
104 |
// 2020-05-03: replaced vec3 'u_Bounding' with a uniform 'vUniforms[effect].w' (i.e. mRadius) |
|
105 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
101 | 106 |
/** |
102 | 107 |
* Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work. |
103 | 108 |
*/ |
... | ... | |
113 | 118 |
+ "vec3 center = vUniforms[effect+1].yzw; \n" |
114 | 119 |
+ "vec3 ps = center-v; \n" |
115 | 120 |
+ "vec3 aPS = abs(ps); \n" |
116 |
+ "vec3 maxps = u_Bounding + abs(center); \n"
|
|
117 |
+ "float d = degree_region(vUniforms[effect+2],ps); \n"
|
|
121 |
+ "vec3 maxps = vUniforms[effect].w + abs(center); \n"
|
|
122 |
+ "float d = degree(vUniforms[effect+2],ps); \n"
|
|
118 | 123 |
+ "vec3 force = vUniforms[effect].xyz * d; \n" |
119 | 124 |
+ "vec3 aForce = abs(force); \n" |
120 | 125 |
+ "float denom = dot(ps+(1.0-d)*force,ps); \n" |
... | ... | |
149 | 154 |
* a (possibly changing in time) point on the Mesh. |
150 | 155 |
* |
151 | 156 |
* @param vector Vector of force that deforms the Mesh. |
157 |
* @param radius How 'bendy' the object is. Don';t set this to 0. Typically set this to the object's |
|
158 |
* mesh size (i.e. more or less X of the rightmost vertex - X of the leftmost vertex) |
|
152 | 159 |
* @param center 3-dimensional Data that, at any given time, returns the Center of the Effect. |
153 | 160 |
* @param region Region that masks the Effect. |
154 | 161 |
*/ |
155 |
public VertexEffectDeform(Data3D vector, Data3D center, Data4D region) |
|
162 |
public VertexEffectDeform(Data3D vector, Data1D radius, Data3D center, Data4D region)
|
|
156 | 163 |
{ |
157 | 164 |
super(EffectName.DEFORM); |
158 | 165 |
mVector = vector; |
166 |
mRadius = radius; |
|
159 | 167 |
mCenter = center; |
160 | 168 |
mRegion = (region==null ? MAX_REGION : region); |
161 | 169 |
} |
... | ... | |
166 | 174 |
* a (possibly changing in time) point on the Mesh. |
167 | 175 |
* |
168 | 176 |
* @param vector Vector of force that deforms the Mesh. |
177 |
* @param radius How 'bendy' the object is. Don't set this to 0. Typically set this to the object's |
|
178 |
* mesh size (i.e. more or less X of the rightmost vertex - X of the leftmost vertex) |
|
169 | 179 |
* @param center 3-dimensional Data that, at any given time, returns the Center of the Effect. |
170 | 180 |
*/ |
171 |
public VertexEffectDeform(Data3D vector, Data3D center) |
|
181 |
public VertexEffectDeform(Data3D vector, Data1D radius, Data3D center)
|
|
172 | 182 |
{ |
173 | 183 |
super(EffectName.DEFORM); |
174 | 184 |
mVector = vector; |
185 |
mRadius = radius; |
|
175 | 186 |
mCenter = center; |
176 | 187 |
mRegion = MAX_REGION; |
177 | 188 |
} |
src/main/java/org/distorted/library/effect/VertexEffectDistort.java | ||
---|---|---|
125 | 125 |
{ |
126 | 126 |
addEffect(EffectName.DISTORT, |
127 | 127 |
|
128 |
"vec3 center = vUniforms[effect+1].yzw; \n" |
|
129 |
+ "vec3 ps = center-v; \n" |
|
128 |
"vec3 ps = vUniforms[effect+1].yzw - v; \n" |
|
130 | 129 |
+ "vec3 force = vUniforms[effect].xyz; \n" |
131 | 130 |
+ "vec4 region= vUniforms[effect+2]; \n" |
132 |
+ "float d = degree(region,center,ps); \n"
|
|
131 |
+ "float d = degree(region,ps); \n"
|
|
133 | 132 |
|
134 | 133 |
+ "if( d>0.0 ) \n" |
135 | 134 |
+ " { \n" |
src/main/java/org/distorted/library/effect/VertexEffectPinch.java | ||
---|---|---|
71 | 71 |
{ |
72 | 72 |
addEffect(EffectName.PINCH, |
73 | 73 |
|
74 |
"vec3 center = vUniforms[effect+1].yzw; \n" |
|
75 |
+ "vec3 ps = center-v; \n" |
|
74 |
"vec3 ps = vUniforms[effect+1].yzw -v; \n" |
|
76 | 75 |
+ "float h = vUniforms[effect].x; \n" |
77 | 76 |
+ "float latitude = vUniforms[effect].y; \n" |
78 | 77 |
+ "float longitude = vUniforms[effect].z; \n" |
79 |
+ "float deg = degree(vUniforms[effect+2],center,ps); \n"
|
|
78 |
+ "float deg = degree(vUniforms[effect+2],ps); \n"
|
|
80 | 79 |
+ "float t = deg * (1.0-h)/max(1.0,h); \n" |
81 | 80 |
+ "float sinLAT = sin(latitude); \n" |
82 | 81 |
+ "float cosLAT = cos(latitude); \n" |
src/main/java/org/distorted/library/effect/VertexEffectSink.java | ||
---|---|---|
60 | 60 |
{ |
61 | 61 |
addEffect(EffectName.SINK, |
62 | 62 |
|
63 |
"vec3 center = vUniforms[effect+1].yzw; \n" |
|
64 |
+ "vec3 ps = center-v; \n" |
|
63 |
"vec3 ps = vUniforms[effect+1].yzw - v; \n" |
|
65 | 64 |
+ "float h = vUniforms[effect].x; \n" |
66 |
+ "float deg = degree(vUniforms[effect+2],center,ps);\n"
|
|
65 |
+ "float deg = degree(vUniforms[effect+2],ps); \n"
|
|
67 | 66 |
+ "float t = deg * (1.0-h)/max(1.0,h); \n" |
68 | 67 |
+ "v += t*ps; \n" |
69 | 68 |
|
src/main/java/org/distorted/library/effect/VertexEffectSwirl.java | ||
---|---|---|
72 | 72 |
"vec3 center = vUniforms[effect+1].yzw; \n" |
73 | 73 |
+ "vec3 PS = center-v.xyz; \n" |
74 | 74 |
+ "vec4 SO = vUniforms[effect+2]; \n" |
75 |
+ "float d1_circle = degree_region(SO,PS); \n" |
|
76 |
+ "float d1_object = degree_object(center,PS); \n" |
|
75 |
+ "float deg1 = degree(SO,PS); \n" |
|
77 | 76 |
+ "float alpha = vUniforms[effect].x; \n" |
78 | 77 |
+ "float sinA = sin(alpha); \n" |
79 | 78 |
+ "float cosA = cos(alpha); \n" |
80 | 79 |
|
81 | 80 |
+ "vec3 PS2 = vec3( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA, PS.z ); \n" // vector PS rotated by A radians clockwise around center. |
82 |
+ "vec4 SG = (1.0-d1_circle)*SO; \n" // coordinates of the dilated circle P is going to get rotated around
|
|
83 |
+ "float d2 = max(0.0,degree(SG,center,PS2)); \n" // make it a max(0,deg) because otherwise when center=left edge of the
|
|
81 |
+ "vec4 SG = (1.0-deg1)*SO; \n" // coordinates of the dilated circle P is going to get rotated around
|
|
82 |
+ "float d2 = max(0.0,degree(SG,PS2)); \n" // make it a max(0,deg) because otherwise when center=left edge of the
|
|
84 | 83 |
// object some points end up with d2<0 and they disappear off view. |
85 |
+ "v.xy += min(d1_circle,d1_object)*(PS.xy - PS2.xy/(1.0-d2)); \n" // if d2=1 (i.e P=center) we should have P unchanged. How to do it?
|
|
84 |
+ "v.xy += deg1 * (PS.xy - PS2.xy/(1.0-d2)); \n" // if d2=1 (i.e P=center) we should have P unchanged. How to do it?
|
|
86 | 85 |
); |
87 | 86 |
} |
88 | 87 |
|
src/main/java/org/distorted/library/effect/VertexEffectWave.java | ||
---|---|---|
129 | 129 |
{ |
130 | 130 |
addEffect(EffectName.WAVE, |
131 | 131 |
|
132 |
"vec3 center = vUniforms[effect+1].yzw; \n" |
|
133 |
+ "float amplitude = vUniforms[effect ].x; \n" |
|
134 |
+ "float length = vUniforms[effect ].y; \n" |
|
132 |
"vec3 center = vUniforms[effect+1].yzw; \n"
|
|
133 |
+ "float amplitude = vUniforms[effect ].x; \n"
|
|
134 |
+ "float length = vUniforms[effect ].y; \n"
|
|
135 | 135 |
|
136 |
+ "vec3 ps = center - v; \n" |
|
137 |
+ "float deg = amplitude*degree_region(vUniforms[effect+2],ps); \n"
|
|
136 |
+ "vec3 ps = center - v; \n"
|
|
137 |
+ "float deg = amplitude*degree(vUniforms[effect+2],ps); \n"
|
|
138 | 138 |
|
139 |
+ "if( deg != 0.0 && length != 0.0 ) \n" |
|
140 |
+ "{ \n" |
|
141 |
+ "float phase = vUniforms[effect ].z; \n" |
|
142 |
+ "float alpha = vUniforms[effect ].w; \n" |
|
143 |
+ "float beta = vUniforms[effect+1].x; \n" |
|
139 |
+ "if( deg != 0.0 && length != 0.0 ) \n"
|
|
140 |
+ "{ \n"
|
|
141 |
+ "float phase = vUniforms[effect ].z; \n"
|
|
142 |
+ "float alpha = vUniforms[effect ].w; \n"
|
|
143 |
+ "float beta = vUniforms[effect+1].x; \n"
|
|
144 | 144 |
|
145 |
+ "float sinA = sin(alpha); \n" |
|
146 |
+ "float cosA = cos(alpha); \n" |
|
147 |
+ "float sinB = sin(beta); \n" |
|
148 |
+ "float cosB = cos(beta); \n" |
|
145 |
+ "float sinA = sin(alpha); \n"
|
|
146 |
+ "float cosA = cos(alpha); \n"
|
|
147 |
+ "float sinB = sin(beta); \n"
|
|
148 |
+ "float cosB = cos(beta); \n"
|
|
149 | 149 |
|
150 | 150 |
+ "float angle= 1.578*(ps.x*cosB-ps.y*sinB) / length + phase; \n" |
151 |
+ "vec3 dir= vec3(sinB*cosA,cosB*cosA,sinA); \n" |
|
152 |
+ "v += sin(angle)*deg*dir; \n" |
|
153 |
|
|
154 |
+ "if( n.z != 0.0 ) \n" |
|
155 |
+ "{ \n" |
|
156 |
+ "float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z); \n" |
|
157 |
+ "float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z); \n" |
|
158 |
|
|
159 |
+ "float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY); \n" |
|
160 |
+ "float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY); \n" |
|
161 |
+ "float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX); \n" |
|
162 |
+ "float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX); \n" |
|
163 |
|
|
164 |
+ "float abs_z = dir.z <0.0 ? -(sinX*sinY) : (sinX*sinY); \n" |
|
165 |
+ "float tmp = 1.578*cos(angle)*deg/length; \n" |
|
166 |
|
|
167 |
+ "float fx =-cosB*tmp; \n" |
|
168 |
+ "float fy = sinB*tmp; \n" |
|
169 |
|
|
170 |
+ "vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,abs_z*fx); \n" |
|
171 |
+ "vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,abs_z*fy); \n" |
|
172 |
|
|
173 |
+ "vec3 normal = cross(sx,sy); \n" |
|
174 |
|
|
175 |
+ "if( normal.z<=0.0 ) \n" // Why this bizarre thing rather than the straightforward
|
|
176 |
+ "{ \n" //
|
|
177 |
+ "normal.x= 0.0; \n" // if( normal.z>0.0 )
|
|
178 |
+ "normal.y= 0.0; \n" // {
|
|
179 |
+ "normal.z= 1.0; \n" // n.x = (n.x*normal.z + n.z*normal.x);
|
|
180 |
+ "} \n" // n.y = (n.y*normal.z + n.z*normal.y);
|
|
181 |
// n.z = (n.z*normal.z); |
|
182 |
// } |
|
183 |
+ "n.x = (n.x*normal.z + n.z*normal.x); \n" //
|
|
184 |
+ "n.y = (n.y*normal.z + n.z*normal.y); \n" // ? Because if we do the above, my Nexus4 crashes
|
|
185 |
+ "n.z = (n.z*normal.z); \n" // during shader compilation!
|
|
186 |
+ "} \n" |
|
151 |
+ "vec3 dir= vec3(sinB*cosA,cosB*cosA,sinA); \n"
|
|
152 |
+ "v += sin(angle)*deg*dir; \n"
|
|
153 |
|
|
154 |
+ "if( n.z != 0.0 ) \n"
|
|
155 |
+ "{ \n"
|
|
156 |
+ "float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z); \n"
|
|
157 |
+ "float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z); \n"
|
|
158 |
|
|
159 |
+ "float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY); \n"
|
|
160 |
+ "float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY); \n"
|
|
161 |
+ "float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX); \n"
|
|
162 |
+ "float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX); \n"
|
|
163 |
|
|
164 |
+ "float abs_z = dir.z <0.0 ? -(sinX*sinY) : (sinX*sinY); \n"
|
|
165 |
+ "float tmp = 1.578*cos(angle)*deg/length; \n"
|
|
166 |
|
|
167 |
+ "float fx =-cosB*tmp; \n"
|
|
168 |
+ "float fy = sinB*tmp; \n"
|
|
169 |
|
|
170 |
+ "vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,abs_z*fx); \n"
|
|
171 |
+ "vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,abs_z*fy); \n"
|
|
172 |
|
|
173 |
+ "vec3 normal = cross(sx,sy); \n"
|
|
174 |
|
|
175 |
+ "if( normal.z<=0.0 ) \n" // Why this bizarre thing rather than the straightforward
|
|
176 |
+ "{ \n" //
|
|
177 |
+ "normal.x= 0.0; \n" // if( normal.z>0.0 )
|
|
178 |
+ "normal.y= 0.0; \n" // {
|
|
179 |
+ "normal.z= 1.0; \n" // n.x = (n.x*normal.z + n.z*normal.x);
|
|
180 |
+ "} \n" // n.y = (n.y*normal.z + n.z*normal.y);
|
|
181 |
// n.z = (n.z*normal.z);
|
|
182 |
// }
|
|
183 |
+ "n.x = (n.x*normal.z + n.z*normal.x); \n" //
|
|
184 |
+ "n.y = (n.y*normal.z + n.z*normal.y); \n" // ? Because if we do the above, my Nexus4 crashes
|
|
185 |
+ "n.z = (n.z*normal.z); \n" // during shader compilation!
|
|
186 |
+ "} \n"
|
|
187 | 187 |
+ "}" |
188 | 188 |
); |
189 | 189 |
} |
src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java | ||
---|---|---|
37 | 37 |
private static float[] mMVPMatrix = new float[16]; |
38 | 38 |
private static float[] mModelViewMatrix = new float[16]; |
39 | 39 |
|
40 |
private static int[] mBoundingH = new int[MAIN_VARIANTS]; |
|
41 | 40 |
private static int[] mStretchH = new int[MAIN_VARIANTS]; |
42 | 41 |
private static int[] mMVPMatrixH = new int[MAIN_VARIANTS]; |
43 | 42 |
private static int[] mMVMatrixH = new int[MAIN_VARIANTS]; |
44 | 43 |
|
45 |
private static float[] mTmpMatrix = new float[16]; |
|
46 |
private static float[] mTmpResult = new float[4]; |
|
47 |
private static float[] mTmpPoint = new float[4]; |
|
48 |
private static float mMinX,mMaxX,mMinY,mMaxY; |
|
49 |
|
|
50 | 44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
51 | 45 |
|
52 | 46 |
EffectQueueMatrix() |
... | ... | |
58 | 52 |
|
59 | 53 |
static void uniforms(int mProgramH, int variant) |
60 | 54 |
{ |
61 |
mBoundingH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_Bounding"); |
|
62 | 55 |
mStretchH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_Stretch"); |
63 | 56 |
mMVPMatrixH[variant]= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix"); |
64 | 57 |
mMVMatrixH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); |
65 | 58 |
} |
66 | 59 |
|
67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
68 |
|
|
69 |
private void magnifyDir() |
|
70 |
{ |
|
71 |
Matrix.multiplyMV(mTmpResult,0,mTmpMatrix,0,mTmpPoint,0); |
|
72 |
float nx = mTmpResult[0]/mTmpResult[3]; |
|
73 |
float ny = mTmpResult[1]/mTmpResult[3]; |
|
74 |
|
|
75 |
if( nx<mMinX ) mMinX = nx; |
|
76 |
if( nx>mMaxX ) mMaxX = nx; |
|
77 |
if( ny<mMinY ) mMinY = ny; |
|
78 |
if( ny>mMaxY ) mMaxY = ny; |
|
79 |
} |
|
80 |
|
|
81 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
82 |
// return a float which describes how much larger an object must be so that it appears to be (about) |
|
83 |
// 'marginInPixels' pixels larger in each direction. Used in Postprocessing. |
|
84 |
|
|
85 |
float magnify(float[] projection, int width, int height, float mipmap, MeshBase mesh, float marginInPixels) |
|
86 |
{ |
|
87 |
mMinX = Integer.MAX_VALUE; |
|
88 |
mMaxX = Integer.MIN_VALUE; |
|
89 |
mMinY = Integer.MAX_VALUE; |
|
90 |
mMaxY = Integer.MIN_VALUE; |
|
91 |
|
|
92 |
mTmpPoint[3] = 1.0f; |
|
93 |
|
|
94 |
Matrix.multiplyMM(mTmpMatrix, 0, projection, 0, mModelViewMatrix, 0); |
|
95 |
|
|
96 |
float halfX = mesh.getBoundingX(); |
|
97 |
float halfY = mesh.getBoundingY(); |
|
98 |
float halfZ = mesh.getBoundingZ(); |
|
99 |
|
|
100 |
mTmpPoint[0] = +halfX; mTmpPoint[1] = +halfY; mTmpPoint[2] = +halfZ; magnifyDir(); |
|
101 |
mTmpPoint[0] = +halfX; mTmpPoint[1] = +halfY; mTmpPoint[2] = -halfZ; magnifyDir(); |
|
102 |
mTmpPoint[0] = +halfX; mTmpPoint[1] = -halfY; mTmpPoint[2] = +halfZ; magnifyDir(); |
|
103 |
mTmpPoint[0] = +halfX; mTmpPoint[1] = -halfY; mTmpPoint[2] = -halfZ; magnifyDir(); |
|
104 |
mTmpPoint[0] = -halfX; mTmpPoint[1] = +halfY; mTmpPoint[2] = +halfZ; magnifyDir(); |
|
105 |
mTmpPoint[0] = -halfX; mTmpPoint[1] = +halfY; mTmpPoint[2] = -halfZ; magnifyDir(); |
|
106 |
mTmpPoint[0] = -halfX; mTmpPoint[1] = -halfY; mTmpPoint[2] = +halfZ; magnifyDir(); |
|
107 |
mTmpPoint[0] = -halfX; mTmpPoint[1] = -halfY; mTmpPoint[2] = -halfZ; magnifyDir(); |
|
108 |
|
|
109 |
float xLenInPixels = width *(mMaxX-mMinX)/2; |
|
110 |
float yLenInPixels = height*(mMaxY-mMinY)/2; |
|
111 |
|
|
112 |
// already margin / avg(xLen,yLen) is the size of the halo. |
|
113 |
// Here we need a bit more because we are marking not only the halo, but a little bit around |
|
114 |
// it as well so that the (blur for example) will be smooth on the edges. Thus the 2.0f. |
|
115 |
// ( 4.0 because there is an extra 2.0 from the avg(xLen,yLen) ) |
|
116 |
// |
|
117 |
// mMipmap ( 1.0, 0.5, 0.25, 0.125 ) - we need to make the size of the halo independent |
|
118 |
// of postprocessing effect quality. |
|
119 |
|
|
120 |
return mipmap*4.0f*marginInPixels/( xLenInPixels+yLenInPixels ); |
|
121 |
} |
|
122 |
|
|
123 | 60 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
124 | 61 |
|
125 | 62 |
void compute(long currTime) |
... | ... | |
164 | 101 |
// combined Model-View-Projection matrix |
165 | 102 |
Matrix.multiplyMM(mMVPMatrix, 0, projection, 0, mModelViewMatrix, 0); |
166 | 103 |
|
167 |
GLES30.glUniform3f( mBoundingH[variant] , mesh.getBoundingX(), mesh.getBoundingY(), mesh.getBoundingZ()); |
|
168 | 104 |
GLES30.glUniform3f( mStretchH[variant] , mesh.getStretchX() , mesh.getStretchY() , mesh.getStretchZ() ); |
169 | 105 |
GLES30.glUniformMatrix4fv(mMVMatrixH[variant] , 1, false, mModelViewMatrix, 0); |
170 | 106 |
GLES30.glUniformMatrix4fv(mMVPMatrixH[variant], 1, false, mMVPMatrix , 0); |
src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java | ||
---|---|---|
178 | 178 |
EffectQueueMatrix matrix = (EffectQueueMatrix)queues[0]; |
179 | 179 |
EffectQueueVertex vertex = (EffectQueueVertex)queues[1]; |
180 | 180 |
|
181 |
float inflate=0.0f; |
|
182 |
|
|
183 | 181 |
matrix.send(distance, mipmap, projection, mesh, 2); |
184 |
|
|
185 |
if( mHalo!=0.0f ) |
|
186 |
{ |
|
187 |
inflate = matrix.magnify(projection, width, height, mipmap, mesh, mHalo); |
|
188 |
} |
|
189 |
|
|
190 |
vertex.send(inflate,2); |
|
182 |
vertex.send(mHalo*0.01f,2); |
|
191 | 183 |
|
192 | 184 |
if( mA!=0.0f ) |
193 | 185 |
{ |
src/main/java/org/distorted/library/mesh/MeshBase.java | ||
---|---|---|
65 | 65 |
private int mNumVertices; |
66 | 66 |
private float[] mVertAttribs; // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ, TexS,TexT |
67 | 67 |
private float mInflate; |
68 |
private float mBoundingX, mBoundingY, mBoundingZ; |
|
69 | 68 |
private float mStretchX, mStretchY, mStretchZ; |
70 | 69 |
|
71 | 70 |
private static class Component |
... | ... | |
99 | 98 |
|
100 | 99 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
101 | 100 |
|
102 |
MeshBase(float bx, float by, float bz)
|
|
101 |
MeshBase() |
|
103 | 102 |
{ |
104 |
mBoundingX = bx/2; |
|
105 |
mBoundingY = by/2; |
|
106 |
mBoundingZ = bz/2; |
|
107 |
|
|
108 | 103 |
mStretchX = 1.0f; |
109 | 104 |
mStretchY = 1.0f; |
110 | 105 |
mStretchZ = 1.0f; |
... | ... | |
122 | 117 |
|
123 | 118 |
MeshBase(MeshBase original) |
124 | 119 |
{ |
125 |
mBoundingX = original.mBoundingX; |
|
126 |
mBoundingY = original.mBoundingY; |
|
127 |
mBoundingZ = original.mBoundingZ; |
|
128 |
|
|
129 | 120 |
mStretchX = original.mStretchX; |
130 | 121 |
mStretchY = original.mStretchY; |
131 | 122 |
mStretchZ = original.mStretchZ; |
... | ... | |
155 | 146 |
return mComponent.size(); |
156 | 147 |
} |
157 | 148 |
|
158 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
159 |
|
|
160 |
void setBounding(float bx, float by, float bz) |
|
161 |
{ |
|
162 |
mBoundingX = bx/2; |
|
163 |
mBoundingY = by/2; |
|
164 |
mBoundingZ = bz/2; |
|
165 |
} |
|
166 |
|
|
167 | 149 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
168 | 150 |
// when a derived class is done computing its mesh, it has to call this method. |
169 | 151 |
|
... | ... | |
533 | 515 |
return (component>=0 && component<mComponent.size()) ? mComponent.get(component).mTextureMap : null; |
534 | 516 |
} |
535 | 517 |
|
536 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
537 |
/** |
|
538 |
* Each mesh has its 'bounding box' - return half of its X-length. |
|
539 |
* <p> |
|
540 |
* In case of all 'simple' Meshes, the bounding box is always 1x1x1 (Sphere, Cubes) or 1x1x0 |
|
541 |
* (Rectangles, Triangles, Quad - i.e. all 'flat' Meshes). But this can be something else in case of |
|
542 |
* MeshComponent. |
|
543 |
*/ |
|
544 |
public float getBoundingX() |
|
545 |
{ |
|
546 |
return mBoundingX*mStretchX; |
|
547 |
} |
|
548 |
|
|
549 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
550 |
/** |
|
551 |
* Each mesh has its 'bounding box' - return half of its Y-length. |
|
552 |
*/ |
|
553 |
public float getBoundingY() |
|
554 |
{ |
|
555 |
return mBoundingY*mStretchY; |
|
556 |
} |
|
557 |
|
|
558 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
559 |
/** |
|
560 |
* Each mesh has its 'bounding box' - return half of its Z-length. |
|
561 |
*/ |
|
562 |
public float getBoundingZ() |
|
563 |
{ |
|
564 |
return mBoundingZ*mStretchZ; |
|
565 |
} |
|
566 |
|
|
567 | 518 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
568 | 519 |
/** |
569 | 520 |
* Sometimes we want to display a Mesh on a rectangular screen. Then we need to stretch it by |
src/main/java/org/distorted/library/mesh/MeshCubes.java | ||
---|---|---|
827 | 827 |
*/ |
828 | 828 |
public MeshCubes(int cols, String desc, int slices) |
829 | 829 |
{ |
830 |
super(1,1,1);
|
|
830 |
super(); |
|
831 | 831 |
Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f); |
832 | 832 |
fillTexMappings(map,map,map,map,map,map); |
833 | 833 |
prepareDataStructures(cols,desc,slices); |
... | ... | |
873 | 873 |
*/ |
874 | 874 |
public MeshCubes(int cols, String desc, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom) |
875 | 875 |
{ |
876 |
super(1,1,1);
|
|
876 |
super(); |
|
877 | 877 |
fillTexMappings(front,back,left,right,top,bottom); |
878 | 878 |
prepareDataStructures(cols,desc,slices); |
879 | 879 |
build(); |
... | ... | |
889 | 889 |
*/ |
890 | 890 |
public MeshCubes(int cols, int rows, int slices) |
891 | 891 |
{ |
892 |
super(1,1,1);
|
|
892 |
super(); |
|
893 | 893 |
Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f); |
894 | 894 |
fillTexMappings(map,map,map,map,map,map); |
895 | 895 |
prepareDataStructures(cols,rows,slices); |
... | ... | |
919 | 919 |
*/ |
920 | 920 |
public MeshCubes(int cols, int rows, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom) |
921 | 921 |
{ |
922 |
super(1,1,1);
|
|
922 |
super(); |
|
923 | 923 |
fillTexMappings(front,back,left,right,top,bottom); |
924 | 924 |
prepareDataStructures(cols,rows,slices); |
925 | 925 |
build(); |
src/main/java/org/distorted/library/mesh/MeshJoined.java | ||
---|---|---|
31 | 31 |
*/ |
32 | 32 |
public MeshJoined(MeshBase[] meshes) |
33 | 33 |
{ |
34 |
super(1,1,1);
|
|
34 |
super(); |
|
35 | 35 |
join(meshes); |
36 | 36 |
} |
37 | 37 |
|
38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
39 |
/** |
|
40 |
* Sets the lengths of the bounding box. |
|
41 |
* <p> |
|
42 |
* The 'bounding box' is an imaginary rectanguloid of size (bx,by,bz) inside of which this Mesh |
|
43 |
* fits tightly. |
|
44 |
* 'Normal' 3D meshes (e.g. Sphere) have this equal to 1,1,1. 'Normal' flat meshes (e.g. Quad) - |
|
45 |
* to 1,1,0. Here however we are joining several, probably already changed by MatrixEffects, |
|
46 |
* Meshes together. If the result fits into the standard 1,1,1 (recommended!) - we don't need to |
|
47 |
* call this function at all. |
|
48 |
* |
|
49 |
* @param bx x-length of the bounding box |
|
50 |
* @param by y-length of the bounding box |
|
51 |
* @param bz z-length of the bounding box |
|
52 |
*/ |
|
53 |
public void setBounding(float bx, float by, float bz) |
|
54 |
{ |
|
55 |
super.setBounding(bx,by,bz); |
|
56 |
} |
|
57 |
|
|
58 | 38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
59 | 39 |
/** |
60 | 40 |
* Return how many basic Meshes is this Mesh joined from. |
src/main/java/org/distorted/library/mesh/MeshQuad.java | ||
---|---|---|
56 | 56 |
*/ |
57 | 57 |
public MeshQuad() |
58 | 58 |
{ |
59 |
super(1,1,0);
|
|
59 |
super(); |
|
60 | 60 |
float[] attribs= new float[VERT_ATTRIBS*4]; |
61 | 61 |
|
62 | 62 |
addVertex(0.0f,0.0f, attribs,0); |
src/main/java/org/distorted/library/mesh/MeshRectangles.java | ||
---|---|---|
158 | 158 |
*/ |
159 | 159 |
public MeshRectangles(int cols, int rows) |
160 | 160 |
{ |
161 |
super(1,1,0);
|
|
161 |
super(); |
|
162 | 162 |
computeNumberOfVertices(cols,rows); |
163 | 163 |
|
164 | 164 |
float[] attribs= new float[VERT_ATTRIBS*numVertices]; |
src/main/java/org/distorted/library/mesh/MeshSphere.java | ||
---|---|---|
253 | 253 |
*/ |
254 | 254 |
public MeshSphere(int level) |
255 | 255 |
{ |
256 |
super(1,1,1);
|
|
256 |
super(); |
|
257 | 257 |
computeNumberOfVertices(level); |
258 | 258 |
float[] attribs= new float[VERT_ATTRIBS*numVertices]; |
259 | 259 |
|
src/main/java/org/distorted/library/mesh/MeshTriangles.java | ||
---|---|---|
107 | 107 |
*/ |
108 | 108 |
public MeshTriangles(int level) |
109 | 109 |
{ |
110 |
super(1,1,0);
|
|
110 |
super(); |
|
111 | 111 |
|
112 | 112 |
computeNumberOfVertices(level); |
113 | 113 |
|
src/main/res/raw/main_vertex_shader.glsl | ||
---|---|---|
31 | 31 |
out vec3 v_Normal; // |
32 | 32 |
out vec2 v_TexCoordinate; // |
33 | 33 |
|
34 |
uniform vec3 u_Bounding; // MeshBase.mBounding{X,Y,Z} |
|
35 | 34 |
uniform vec3 u_Stretch; // MeshBase.mStretch{X,Y,Z} |
36 | 35 |
uniform mat4 u_MVPMatrix; // the combined model/view/projection matrix. |
37 | 36 |
uniform mat4 u_MVMatrix; // the combined model/view matrix. |
... | ... | |
46 | 45 |
|
47 | 46 |
////////////////////////////////////////////////////////////////////////////////////////////// |
48 | 47 |
// HELPER FUNCTIONS |
49 |
////////////////////////////////////////////////////////////////////////////////////////////// |
|
50 |
// The trick below is the if-less version of the |
|
51 |
// |
|
52 |
// t = dx<0.0 ? (u_Bounding.x-v.x) / (u_Bounding.x-ux) : (u_Bounding.x+v.x) / (u_Bounding.x+ux); |
|
53 |
// h = dy<0.0 ? (u_Bounding.y-v.y) / (u_Bounding.y-uy) : (u_Bounding.y+v.y) / (u_Bounding.y+uy); |
|
54 |
// d = min(t,h); |
|
55 |
// |
|
56 |
// float d = min(-ps.x/(sign(ps.x)*u_Bounding.x+p.x),-ps.y/(sign(ps.y)*u_Bounding.y+p.y))+1.0; |
|
57 |
// |
|
58 |
// We still have to avoid division by 0 when p.x = +- u_Bounding.x or p.y = +- u_Bounding.y (i.e |
|
59 |
// on the edge of the Object). |
|
60 |
// We do that by first multiplying the above 'float d' with sign(denominator1*denominator2)^2. |
|
61 |
// |
|
62 |
// 2019-01-09: make this 3D. The trick: we want only the EDGES of the cuboid to stay constant. |
|
63 |
// the interiors of the Faces move! Thus, we want the MIDDLE of the PS/(sign(PS)*u_Bounding+S) ! |
|
64 |
////////////////////////////////////////////////////////////////////////////////////////////// |
|
65 |
// return degree of the point as defined by the cuboid (u_Bounding.x X u_Bounding.y X u_Bounding.z) |
|
66 |
|
|
67 |
float degree_object(in vec3 S, in vec3 PS) |
|
68 |
{ |
|
69 |
vec3 ONE = vec3(1.0,1.0,1.0); |
|
70 |
vec3 A = sign(PS)*u_Bounding + S; |
|
71 |
|
|
72 |
vec3 signA = sign(A); // |
|
73 |
vec3 signA_SQ = signA*signA; // div = PS/A if A!=0, 0 otherwise. |
|
74 |
vec3 div = signA_SQ*PS/(A-(ONE-signA_SQ)); // |
|
75 |
vec3 ret = sign(u_Bounding)-div; |
|
76 |
|
|
77 |
float d1= ret.x-ret.y; |
|
78 |
float d2= ret.y-ret.z; |
|
79 |
float d3= ret.x-ret.z; |
|
80 |
|
|
81 |
if( d1*d2>0.0 ) return ret.y; // |
|
82 |
if( d1*d3>0.0 ) return ret.z; // return 1-middle(div.x,div.y,div.z) |
|
83 |
return ret.x; // (unless size of object is 0 then 0-middle) |
|
84 |
} |
|
85 |
|
|
86 | 48 |
////////////////////////////////////////////////////////////////////////////////////////////// |
87 | 49 |
// Return degree of the point as defined by the Region. Currently only supports spherical regions. |
88 | 50 |
// |
... | ... | |
103 | 65 |
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and |
104 | 66 |
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt. |
105 | 67 |
|
106 |
float degree_region(in vec4 region, in vec3 PS)
|
|
68 |
float degree(in vec4 region, in vec3 PS) |
|
107 | 69 |
{ |
108 | 70 |
vec3 PO = PS + region.xyz; |
109 | 71 |
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2 |
... | ... | |
125 | 87 |
return 1.0 / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)); |
126 | 88 |
} |
127 | 89 |
|
128 |
////////////////////////////////////////////////////////////////////////////////////////////// |
|
129 |
// return min(degree_object,degree_region). Just like degree_region, currently only supports spheres. |
|
130 |
|
|
131 |
float degree(in vec4 region, in vec3 S, in vec3 PS) |
|
132 |
{ |
|
133 |
vec3 PO = PS + region.xyz; |
|
134 |
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2 |
|
135 |
|
|
136 |
if( D<=0.0 ) return 0.0; |
|
137 |
|
|
138 |
vec3 A = sign(PS)*u_Bounding + S; |
|
139 |
vec3 signA = sign(A); |
|
140 |
vec3 signA_SQ = signA*signA; |
|
141 |
vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ)); |
|
142 |
vec3 ret = sign(u_Bounding)-div; // if object is flat, make ret.z 0 |
|
143 |
|
|
144 |
float d1= ret.x-ret.y; |
|
145 |
float d2= ret.y-ret.z; |
|
146 |
float d3= ret.x-ret.z; |
|
147 |
float degree_object; |
|
148 |
|
|
149 |
if( d1*d2>0.0 ) degree_object= ret.y; // |
|
150 |
else if( d1*d3>0.0 ) degree_object= ret.z; // middle of the ret.{x,y,z} triple |
|
151 |
else degree_object= ret.x; // |
|
152 |
|
|
153 |
float ps_sq = dot(PS,PS); |
|
154 |
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0 |
|
155 |
float DOT = dot(PS,PO)*one_over_ps_sq; |
|
156 |
float degree_region = 1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)); |
|
157 |
|
|
158 |
return min(degree_region,degree_object); |
|
159 |
} |
|
160 |
|
|
161 | 90 |
#endif // NUM_VERTEX>0 |
162 | 91 |
|
163 | 92 |
////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
A lot of changes.
1) main vertex shader: remove support for degree_object. This functionality will hopefully come back when we introduce other than circular regions.
2) MeshBase: remove the need to set a Bounding box (this is the point of the whole thing - we wanted to get rid of this so that the advances in MeshJoined will be easier)
3) Set ground for removing the MeshBase.setStretch / getStretch (another thing needed to advance MeshJoined )
4) since we removed the Bounding box, we need to change the DEFORN effect to have 1 additional parameter, the 'radius' which takes over the function of the bounding box in the vertex shader.
5) since the'res no bounding box, simplify the postprocessing Halo (remove EffectQueueMatrix.magnify() )
6) adjust applications.
After this we will hopefully be ready to introduce MeshBase.preApply(VertexEffect), i.e. bending several simple Meshes with any VertexEffect - including the freshly-introduced PseudoMatrix-Vertex effects like VertexEffectScale - and then combining them into one MeshJoined.