Revision 0f10a0b6
Added by Leszek Koltunski over 5 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.