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.