Revision 033e8feb
Added by Leszek Koltunski 6 months ago
| src/main/java/org/distorted/library/mesh/DeferredJobs.kt | ||
|---|---|---|
| 18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
| 19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 20 | 20 |
|
| 21 |
package org.distorted.library.mesh;
|
|
| 21 |
package org.distorted.library.mesh |
|
| 22 | 22 |
|
| 23 |
import org.distorted.library.effect.MatrixEffect; |
|
| 24 |
import org.distorted.library.effect.VertexEffect; |
|
| 25 |
import org.distorted.library.effectqueue.EffectQueueVertex; |
|
| 26 |
import org.distorted.library.main.DistortedLibrary; |
|
| 27 |
import org.distorted.library.type.Static4D; |
|
| 28 |
|
|
| 29 |
import java.util.ArrayList; |
|
| 23 |
import org.distorted.library.effect.MatrixEffect |
|
| 24 |
import org.distorted.library.effect.VertexEffect |
|
| 25 |
import org.distorted.library.effectqueue.EffectQueueVertex |
|
| 26 |
import org.distorted.library.main.DistortedLibrary |
|
| 27 |
import org.distorted.library.type.Static4D |
|
| 30 | 28 |
|
| 31 | 29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 32 | 30 |
/** |
| ... | ... | |
| 34 | 32 |
* |
| 35 | 33 |
* @y.exclude |
| 36 | 34 |
*/ |
| 37 |
public class DeferredJobs |
|
| 38 |
{
|
|
| 39 |
private static final int JOB_TYPE_VERTEX = 0; |
|
| 40 |
private static final int JOB_TYPE_MATRIX = 1; |
|
| 41 |
private static final int JOB_TYPE_MERGE_TEX = 2; |
|
| 42 |
private static final int JOB_TYPE_MERGE_EFF = 3; |
|
| 43 |
private static final int JOB_TYPE_JOIN = 4; |
|
| 44 |
private static final int JOB_TYPE_COPY = 5; |
|
| 45 |
private static final int JOB_TYPE_TEXTURE = 6; |
|
| 46 |
private static final int JOB_TYPE_ASSOC = 7; |
|
| 47 |
private static final int JOB_TYPE_CENTER = 8; |
|
| 48 |
private static final int JOB_TYPE_ADD_EMPTY_TEX= 9; |
|
| 49 |
private static final int JOB_TYPE_NOT_AFFECTED = 10; |
|
| 50 |
|
|
| 51 |
private static final ArrayList<JobNode> mJobs = new ArrayList<>(); |
|
| 52 |
|
|
| 53 |
////////////////////////////////////////////////////////////////////////// |
|
| 54 |
|
|
| 55 |
private static class Job |
|
| 35 |
object DeferredJobs |
|
| 36 |
{
|
|
| 37 |
private const val JOB_TYPE_VERTEX = 0 |
|
| 38 |
private const val JOB_TYPE_MATRIX = 1 |
|
| 39 |
private const val JOB_TYPE_MERGE_TEX = 2 |
|
| 40 |
private const val JOB_TYPE_MERGE_EFF = 3 |
|
| 41 |
private const val JOB_TYPE_JOIN = 4 |
|
| 42 |
private const val JOB_TYPE_COPY = 5 |
|
| 43 |
private const val JOB_TYPE_TEXTURE = 6 |
|
| 44 |
private const val JOB_TYPE_ASSOC = 7 |
|
| 45 |
private const val JOB_TYPE_CENTER = 8 |
|
| 46 |
private const val JOB_TYPE_ADD_EMPTY_TEX = 9 |
|
| 47 |
private const val JOB_TYPE_NOT_AFFECTED = 10 |
|
| 48 |
|
|
| 49 |
private val mJobs = ArrayList<JobNode>() |
|
| 50 |
|
|
| 51 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 52 |
private fun removeNode(node: JobNode) |
|
| 56 | 53 |
{
|
| 57 |
private final int mType; |
|
| 58 |
private final MeshBase mTarget; |
|
| 59 |
private final MeshBase[] mSource; |
|
| 60 |
private final MatrixEffect mMatrixEffect; |
|
| 61 |
private final Static4D[] mMaps; |
|
| 62 |
private final int mComp, mAndAssoc, mEquAssoc; |
|
| 63 |
private final float mX,mY,mZ; |
|
| 64 |
private final int[] mComps; |
|
| 65 |
|
|
| 66 |
private EffectQueueVertex mVertexEffects; |
|
| 67 |
|
|
| 68 |
Job(int type, MeshBase target, MeshBase[] source, VertexEffect vEff, MatrixEffect mEff, |
|
| 69 |
Static4D[] maps, int comp, int and, int equ, float x, float y, float z, int[] comps) |
|
| 70 |
{
|
|
| 71 |
mType = type; |
|
| 72 |
mTarget = target; |
|
| 73 |
mSource = source; |
|
| 74 |
mMaps = maps; |
|
| 75 |
mComp = comp; |
|
| 76 |
mAndAssoc = and; |
|
| 77 |
mEquAssoc = equ; |
|
| 78 |
mX = x; |
|
| 79 |
mY = y; |
|
| 80 |
mZ = z; |
|
| 81 |
mComps = comps; |
|
| 82 |
|
|
| 83 |
if( vEff!=null ) |
|
| 84 |
{
|
|
| 85 |
mVertexEffects= new EffectQueueVertex(); |
|
| 86 |
mVertexEffects.add(vEff); |
|
| 87 |
} |
|
| 54 |
mJobs.remove(node) |
|
| 55 |
var jn: JobNode? |
|
| 88 | 56 |
|
| 89 |
mMatrixEffect = mEff; |
|
| 90 |
} |
|
| 57 |
val numPrev = node.mPrevJobs!!.size |
|
| 91 | 58 |
|
| 92 |
void addEffect(VertexEffect effect) |
|
| 93 |
{
|
|
| 94 |
mVertexEffects.add(effect); |
|
| 95 |
} |
|
| 96 |
|
|
| 97 |
void execute() |
|
| 98 |
{
|
|
| 99 |
switch(mType) |
|
| 59 |
for (i in 0 until numPrev) |
|
| 100 | 60 |
{
|
| 101 |
case JOB_TYPE_VERTEX : DistortedLibrary.adjustVertices(mTarget, mVertexEffects); |
|
| 102 |
break; |
|
| 103 |
case JOB_TYPE_MATRIX : mTarget.applyMatrix(mMatrixEffect,mAndAssoc,mEquAssoc); |
|
| 104 |
break; |
|
| 105 |
case JOB_TYPE_MERGE_TEX : mTarget.mergeTexComponentsNow(); |
|
| 106 |
break; |
|
| 107 |
case JOB_TYPE_MERGE_EFF : mTarget.mergeEffComponentsNow(); |
|
| 108 |
break; |
|
| 109 |
case JOB_TYPE_JOIN : mTarget.joinAttribs(mSource); |
|
| 110 |
break; |
|
| 111 |
case JOB_TYPE_COPY : mTarget.copy(mSource[0]); |
|
| 112 |
break; |
|
| 113 |
case JOB_TYPE_TEXTURE : mTarget.textureMap(mMaps,mComp); |
|
| 114 |
break; |
|
| 115 |
case JOB_TYPE_ASSOC : mTarget.setEffectAssociationNow(mComp,mAndAssoc,mEquAssoc); |
|
| 116 |
break; |
|
| 117 |
case JOB_TYPE_CENTER : mTarget.setComponentCenterNow(mComp,mX,mY,mZ); |
|
| 118 |
break; |
|
| 119 |
case JOB_TYPE_ADD_EMPTY_TEX: mTarget.addEmptyTexComponentNow(); |
|
| 120 |
break; |
|
| 121 |
case JOB_TYPE_NOT_AFFECTED: mTarget.setNotAffectedComponentsNow(mComps); |
|
| 61 |
jn = node.mPrevJobs!![i] |
|
| 62 |
jn!!.mNextJobs!!.remove(node) |
|
| 122 | 63 |
} |
| 123 |
} |
|
| 124 | 64 |
|
| 125 |
void clear() |
|
| 126 |
{
|
|
| 127 |
if( mVertexEffects!=null ) mVertexEffects.removeAll(false); |
|
| 128 |
} |
|
| 65 |
val numNext = node.mNextJobs!!.size |
|
| 129 | 66 |
|
| 130 |
String print() |
|
| 131 |
{
|
|
| 132 |
switch(mType) |
|
| 67 |
for (i in 0 until numNext) |
|
| 133 | 68 |
{
|
| 134 |
case JOB_TYPE_VERTEX : return "VERTEX"; |
|
| 135 |
case JOB_TYPE_MATRIX : return "MATRIX"; |
|
| 136 |
case JOB_TYPE_MERGE_TEX : return "MERGE_TEX"; |
|
| 137 |
case JOB_TYPE_MERGE_EFF : return "MERGE_EFF"; |
|
| 138 |
case JOB_TYPE_JOIN : return "JOIN"; |
|
| 139 |
case JOB_TYPE_COPY : return "COPY"; |
|
| 140 |
case JOB_TYPE_TEXTURE : return "TEXTURE"; |
|
| 141 |
case JOB_TYPE_ASSOC : return "ASSOC"; |
|
| 142 |
case JOB_TYPE_CENTER : return "CENTER"; |
|
| 143 |
case JOB_TYPE_ADD_EMPTY_TEX: return "ADD_EMPTY_TEX"; |
|
| 144 |
case JOB_TYPE_NOT_AFFECTED : return "POSTPROC COMPS"; |
|
| 69 |
jn = node.mNextJobs!![i] |
|
| 70 |
jn!!.mPrevJobs!!.remove(node) |
|
| 145 | 71 |
} |
| 146 | 72 |
|
| 147 |
return null; |
|
| 148 |
} |
|
| 73 |
node.mJob!!.mTarget.mJobNode[0] = null |
|
| 149 | 74 |
} |
| 150 | 75 |
|
| 151 |
////////////////////////////////////////////////////////////////////////// |
|
| 152 |
|
|
| 153 |
static class JobNode |
|
| 76 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 77 |
fun vertex(target: MeshBase, effect: VertexEffect?): JobNode |
|
| 154 | 78 |
{
|
| 155 |
private ArrayList<JobNode> mPrevJobs; |
|
| 156 |
private ArrayList<JobNode> mNextJobs; |
|
| 157 |
private Job mJob; |
|
| 158 |
|
|
| 159 |
JobNode(Job job) |
|
| 160 |
{
|
|
| 161 |
mPrevJobs = new ArrayList<>(); |
|
| 162 |
mNextJobs = new ArrayList<>(); |
|
| 163 |
mJob = job; |
|
| 164 |
} |
|
| 165 |
|
|
| 166 |
synchronized void execute() |
|
| 167 |
{
|
|
| 168 |
if( mPrevJobs!=null ) |
|
| 169 |
{
|
|
| 170 |
JobNode node; |
|
| 171 |
int numPrev = mPrevJobs.size(); |
|
| 79 |
val jn = target.mJobNode[0] |
|
| 172 | 80 |
|
| 173 |
for(int i=0; i<numPrev; i++) |
|
| 174 |
{
|
|
| 175 |
node = mPrevJobs.get(0); // removeNode() rips the executed job out, thus the 0 |
|
| 176 |
node.execute(); |
|
| 177 |
} |
|
| 178 |
|
|
| 179 |
removeNode(this); |
|
| 180 |
mJob.execute(); |
|
| 81 |
if (jn==null) |
|
| 82 |
{
|
|
| 83 |
val job = Job(JOB_TYPE_VERTEX, target, null, effect, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 84 |
val node = JobNode(job) |
|
| 85 |
mJobs.add(node) |
|
| 86 |
return node |
|
| 181 | 87 |
} |
| 182 |
} |
|
| 183 |
|
|
| 184 |
synchronized void clear() |
|
| 185 |
{
|
|
| 186 |
mPrevJobs.clear(); |
|
| 187 |
mPrevJobs = null; |
|
| 188 |
mNextJobs.clear(); |
|
| 189 |
mNextJobs = null; |
|
| 190 |
|
|
| 191 |
mJob.clear(); |
|
| 192 |
mJob = null; |
|
| 193 |
} |
|
| 194 |
|
|
| 195 |
void print(int level) |
|
| 196 |
{
|
|
| 197 |
int numPrev = mPrevJobs.size(); |
|
| 198 |
int numNext = mNextJobs.size(); |
|
| 199 |
|
|
| 200 |
String str = ""; |
|
| 201 |
for(int i=0; i<level; i++) str+=" "; |
|
| 202 |
|
|
| 203 |
str += mJob.print(); |
|
| 204 |
|
|
| 205 |
str += (" next: "+numNext+" prev: "+numPrev);
|
|
| 206 |
|
|
| 207 |
DistortedLibrary.logMessage("DeferredJobs: "+str);
|
|
| 208 |
|
|
| 209 |
for(int i=0; i<numPrev; i++) |
|
| 88 |
else |
|
| 210 | 89 |
{
|
| 211 |
JobNode node = mPrevJobs.get(i); |
|
| 212 |
node.print(level+1); |
|
| 90 |
if (jn.mJob!!.mType==JOB_TYPE_VERTEX) |
|
| 91 |
{
|
|
| 92 |
jn.mJob!!.addEffect(effect) |
|
| 93 |
return jn |
|
| 94 |
} |
|
| 95 |
else |
|
| 96 |
{
|
|
| 97 |
val job = Job(JOB_TYPE_VERTEX, target, null, effect, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 98 |
val node = JobNode(job) |
|
| 99 |
node.mPrevJobs!!.add(jn) |
|
| 100 |
jn.mNextJobs!!.add(node) |
|
| 101 |
mJobs.add(node) |
|
| 102 |
return node |
|
| 103 |
} |
|
| 213 | 104 |
} |
| 214 |
} |
|
| 215 | 105 |
} |
| 216 | 106 |
|
| 217 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 218 |
|
|
| 219 |
private static void removeNode(JobNode node) |
|
| 107 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 108 |
fun matrix(target: MeshBase, effect: MatrixEffect?, andAssoc: Int, ecuAssoc: Int): JobNode |
|
| 220 | 109 |
{
|
| 221 |
mJobs.remove(node); |
|
| 222 |
JobNode jn; |
|
| 223 |
|
|
| 224 |
int numPrev = node.mPrevJobs.size(); |
|
| 225 |
|
|
| 226 |
for(int i=0; i<numPrev; i++) |
|
| 227 |
{
|
|
| 228 |
jn = node.mPrevJobs.get(i); |
|
| 229 |
jn.mNextJobs.remove(node); |
|
| 230 |
} |
|
| 231 |
|
|
| 232 |
int numNext = node.mNextJobs.size(); |
|
| 110 |
val jn = target.mJobNode[0] |
|
| 111 |
val job = Job(JOB_TYPE_MATRIX, target, null, null, effect, null, 0, andAssoc, ecuAssoc, 0f, 0f, 0f, null) |
|
| 112 |
val node = JobNode(job) |
|
| 113 |
node.mPrevJobs!!.add(jn) |
|
| 114 |
jn!!.mNextJobs!!.add(node) |
|
| 115 |
mJobs.add(node) |
|
| 116 |
return node |
|
| 117 |
} |
|
| 233 | 118 |
|
| 234 |
for(int i=0; i<numNext; i++) |
|
| 235 |
{
|
|
| 236 |
jn = node.mNextJobs.get(i); |
|
| 237 |
jn.mPrevJobs.remove(node); |
|
| 238 |
} |
|
| 119 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 120 |
fun mergeTex(target: MeshBase): JobNode |
|
| 121 |
{
|
|
| 122 |
val jn = target.mJobNode[0] |
|
| 123 |
val job = Job(JOB_TYPE_MERGE_TEX, target, null, null, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 124 |
val node = JobNode(job) |
|
| 125 |
node.mPrevJobs!!.add(jn) |
|
| 126 |
jn!!.mNextJobs!!.add(node) |
|
| 127 |
mJobs.add(node) |
|
| 128 |
return node |
|
| 129 |
} |
|
| 239 | 130 |
|
| 240 |
node.mJob.mTarget.mJobNode[0] = null; |
|
| 131 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 132 |
fun addEmptyTex(target: MeshBase): JobNode |
|
| 133 |
{
|
|
| 134 |
val jn = target.mJobNode[0] |
|
| 135 |
val job = Job(JOB_TYPE_ADD_EMPTY_TEX, target, null, null, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 136 |
val node = JobNode(job) |
|
| 137 |
node.mPrevJobs!!.add(jn) |
|
| 138 |
jn!!.mNextJobs!!.add(node) |
|
| 139 |
mJobs.add(node) |
|
| 140 |
return node |
|
| 241 | 141 |
} |
| 242 | 142 |
|
| 243 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 143 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 144 |
fun mergeEff(target: MeshBase): JobNode |
|
| 145 |
{
|
|
| 146 |
val jn = target.mJobNode[0] |
|
| 147 |
val job = Job(JOB_TYPE_MERGE_EFF, target, null, null, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 148 |
val node = JobNode(job) |
|
| 149 |
node.mPrevJobs!!.add(jn) |
|
| 150 |
jn!!.mNextJobs!!.add(node) |
|
| 151 |
mJobs.add(node) |
|
| 152 |
return node |
|
| 153 |
} |
|
| 244 | 154 |
|
| 245 |
static JobNode vertex(MeshBase target, VertexEffect effect) |
|
| 155 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 156 |
fun join(target: MeshBase, meshes: Array<MeshBase>): JobNode |
|
| 246 | 157 |
{
|
| 247 |
JobNode jn = target.mJobNode[0]; |
|
| 248 |
|
|
| 249 |
if( jn==null ) |
|
| 250 |
{
|
|
| 251 |
Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null); |
|
| 252 |
JobNode node = new JobNode(job); |
|
| 253 |
mJobs.add(node); |
|
| 254 |
return node; |
|
| 255 |
} |
|
| 256 |
else |
|
| 257 |
{
|
|
| 258 |
if( jn.mJob.mType==JOB_TYPE_VERTEX ) |
|
| 259 |
{
|
|
| 260 |
jn.mJob.addEffect(effect); |
|
| 261 |
return jn; |
|
| 262 |
} |
|
| 263 |
else |
|
| 158 |
var jn: JobNode? |
|
| 159 |
|
|
| 160 |
val job = Job(JOB_TYPE_JOIN, target, meshes, null, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 161 |
val node = JobNode(job) |
|
| 162 |
|
|
| 163 |
for (mesh in meshes) |
|
| 264 | 164 |
{
|
| 265 |
Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null); |
|
| 266 |
JobNode node = new JobNode(job); |
|
| 267 |
node.mPrevJobs.add(jn); |
|
| 268 |
jn.mNextJobs.add(node); |
|
| 269 |
mJobs.add(node); |
|
| 270 |
return node; |
|
| 165 |
jn = mesh.mJobNode[0] |
|
| 166 |
|
|
| 167 |
if (jn!=null) |
|
| 168 |
{
|
|
| 169 |
node.mPrevJobs!!.add(jn) |
|
| 170 |
jn.mNextJobs!!.add(node) |
|
| 171 |
} |
|
| 271 | 172 |
} |
| 272 |
} |
|
| 273 |
} |
|
| 274 | 173 |
|
| 275 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 174 |
mJobs.add(node) |
|
| 175 |
return node |
|
| 176 |
} |
|
| 276 | 177 |
|
| 277 |
static JobNode matrix(MeshBase target, MatrixEffect effect, int andAssoc, int ecuAssoc) |
|
| 178 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 179 |
fun copy(target: MeshBase, mesh: MeshBase): JobNode |
|
| 278 | 180 |
{
|
| 279 |
JobNode jn = target.mJobNode[0]; |
|
| 280 |
Job job = new Job(JOB_TYPE_MATRIX,target,null,null,effect,null,0,andAssoc,ecuAssoc,0,0,0,null); |
|
| 281 |
JobNode node = new JobNode(job); |
|
| 282 |
node.mPrevJobs.add(jn); |
|
| 283 |
jn.mNextJobs.add(node); |
|
| 284 |
mJobs.add(node); |
|
| 285 |
return node; |
|
| 181 |
val jn = mesh.mJobNode[0] |
|
| 182 |
val meshes = arrayOfNulls<MeshBase>(1) |
|
| 183 |
meshes[0] = mesh |
|
| 184 |
val job = Job(JOB_TYPE_COPY, target, meshes, null, null, null, 0, 0, 0, 0f, 0f, 0f, null) |
|
| 185 |
val node = JobNode(job) |
|
| 186 |
node.mPrevJobs!!.add(jn) |
|
| 187 |
jn!!.mNextJobs!!.add(node) |
|
| 188 |
mJobs.add(node) |
|
| 189 |
return node |
|
| 286 | 190 |
} |
| 287 | 191 |
|
| 288 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 289 |
|
|
| 290 |
static JobNode mergeTex(MeshBase target) |
|
| 192 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 193 |
fun textureMap(target: MeshBase, maps: Array<Static4D?>?, comp: Int): JobNode |
|
| 291 | 194 |
{
|
| 292 |
JobNode jn = target.mJobNode[0];
|
|
| 293 |
Job job = new Job(JOB_TYPE_MERGE_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
|
|
| 294 |
JobNode node = new JobNode(job);
|
|
| 295 |
node.mPrevJobs.add(jn);
|
|
| 296 |
jn.mNextJobs.add(node);
|
|
| 297 |
mJobs.add(node);
|
|
| 298 |
return node;
|
|
| 195 |
val jn = target.mJobNode[0]
|
|
| 196 |
val job = Job(JOB_TYPE_TEXTURE, target, null, null, null, maps, comp, 0, 0, 0f, 0f, 0f, null)
|
|
| 197 |
val node = JobNode(job)
|
|
| 198 |
node.mPrevJobs!!.add(jn)
|
|
| 199 |
jn!!.mNextJobs!!.add(node)
|
|
| 200 |
mJobs.add(node)
|
|
| 201 |
return node
|
|
| 299 | 202 |
} |
| 300 | 203 |
|
| 301 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 302 |
|
|
| 303 |
static JobNode addEmptyTex(MeshBase target) |
|
| 204 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 205 |
fun effectAssoc(target: MeshBase, comp: Int, andAssoc: Int, equAssoc: Int): JobNode |
|
| 304 | 206 |
{
|
| 305 |
JobNode jn = target.mJobNode[0];
|
|
| 306 |
Job job = new Job(JOB_TYPE_ADD_EMPTY_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
|
|
| 307 |
JobNode node = new JobNode(job);
|
|
| 308 |
node.mPrevJobs.add(jn);
|
|
| 309 |
jn.mNextJobs.add(node);
|
|
| 310 |
mJobs.add(node);
|
|
| 311 |
return node;
|
|
| 207 |
val jn = target.mJobNode[0]
|
|
| 208 |
val job = Job(JOB_TYPE_ASSOC, target, null, null, null, null, comp, andAssoc, equAssoc, 0f, 0f, 0f, null)
|
|
| 209 |
val node = JobNode(job)
|
|
| 210 |
node.mPrevJobs!!.add(jn)
|
|
| 211 |
jn!!.mNextJobs!!.add(node)
|
|
| 212 |
mJobs.add(node)
|
|
| 213 |
return node
|
|
| 312 | 214 |
} |
| 313 | 215 |
|
| 314 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 315 |
|
|
| 316 |
static JobNode mergeEff(MeshBase target) |
|
| 216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 217 |
fun componentCenter(target: MeshBase, comp: Int, x: Float, y: Float, z: Float): JobNode |
|
| 317 | 218 |
{
|
| 318 |
JobNode jn = target.mJobNode[0];
|
|
| 319 |
Job job = new Job(JOB_TYPE_MERGE_EFF,target,null,null,null,null,0,0,0,0,0,0,null);
|
|
| 320 |
JobNode node = new JobNode(job);
|
|
| 321 |
node.mPrevJobs.add(jn);
|
|
| 322 |
jn.mNextJobs.add(node);
|
|
| 323 |
mJobs.add(node);
|
|
| 324 |
return node;
|
|
| 219 |
val jn = target.mJobNode[0]
|
|
| 220 |
val job = Job(JOB_TYPE_CENTER, target, null, null, null, null, comp, 0, 0, x, y, z, null)
|
|
| 221 |
val node = JobNode(job)
|
|
| 222 |
node.mPrevJobs!!.add(jn)
|
|
| 223 |
jn!!.mNextJobs!!.add(node)
|
|
| 224 |
mJobs.add(node)
|
|
| 225 |
return node
|
|
| 325 | 226 |
} |
| 326 | 227 |
|
| 327 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 228 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 229 |
fun setNotAffected(target: MeshBase, comps: IntArray?): JobNode |
|
| 230 |
{
|
|
| 231 |
val jn = target.mJobNode[0] |
|
| 232 |
val job = Job(JOB_TYPE_NOT_AFFECTED, target, null, null, null, null, 0, 0, 0, 0f, 0f, 0f, comps) |
|
| 233 |
val node = JobNode(job) |
|
| 234 |
node.mPrevJobs!!.add(jn) |
|
| 235 |
jn!!.mNextJobs!!.add(node) |
|
| 236 |
mJobs.add(node) |
|
| 237 |
return node |
|
| 238 |
} |
|
| 328 | 239 |
|
| 329 |
static JobNode join(MeshBase target, MeshBase[] meshes) |
|
| 240 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 241 |
/** |
|
| 242 |
* Only for use by the library itself. |
|
| 243 |
* |
|
| 244 |
* @y.exclude |
|
| 245 |
*/ |
|
| 246 |
@JvmStatic |
|
| 247 |
fun onPause() |
|
| 330 | 248 |
{
|
| 331 |
JobNode jn; |
|
| 249 |
val num = mJobs.size |
|
| 250 |
for (i in 0 until num) mJobs[i].clear() |
|
| 251 |
mJobs.clear() |
|
| 252 |
} |
|
| 332 | 253 |
|
| 333 |
Job job = new Job(JOB_TYPE_JOIN,target,meshes,null,null,null,0,0,0,0,0,0,null); |
|
| 334 |
JobNode node = new JobNode(job); |
|
| 254 |
////////////////////////////////////////////////////////////////////////// |
|
| 255 |
class Job |
|
| 256 |
(val mType: Int, val mTarget: MeshBase, source: Array<MeshBase?>?, vEff: VertexEffect?, mEff: MatrixEffect?, |
|
| 257 |
maps: Array<Static4D?>?, comp: Int, and: Int, equ: Int, x: Float, y: Float, z: Float, comps: IntArray?) |
|
| 258 |
{
|
|
| 259 |
private val mSource = source!! |
|
| 260 |
private val mMatrixEffect: MatrixEffect |
|
| 261 |
private val mMaps = maps!! |
|
| 262 |
private val mComp = comp |
|
| 263 |
private val mAndAssoc = and |
|
| 264 |
private val mEquAssoc = equ |
|
| 265 |
private val mX = x |
|
| 266 |
private val mY = y |
|
| 267 |
private val mZ = z |
|
| 268 |
private val mComps = comps |
|
| 269 |
|
|
| 270 |
private var mVertexEffects: EffectQueueVertex? = null |
|
| 271 |
|
|
| 272 |
init |
|
| 273 |
{
|
|
| 274 |
if (vEff!=null) |
|
| 275 |
{
|
|
| 276 |
mVertexEffects = EffectQueueVertex() |
|
| 277 |
mVertexEffects!!.add(vEff) |
|
| 278 |
} |
|
| 335 | 279 |
|
| 336 |
for (MeshBase mesh : meshes) |
|
| 337 |
{
|
|
| 338 |
jn = mesh.mJobNode[0]; |
|
| 280 |
mMatrixEffect = mEff!! |
|
| 281 |
} |
|
| 339 | 282 |
|
| 340 |
if( jn!=null )
|
|
| 283 |
fun addEffect(effect: VertexEffect?)
|
|
| 341 | 284 |
{
|
| 342 |
node.mPrevJobs.add(jn); |
|
| 343 |
jn.mNextJobs.add(node); |
|
| 285 |
mVertexEffects!!.add(effect) |
|
| 344 | 286 |
} |
| 345 |
} |
|
| 346 | 287 |
|
| 347 |
mJobs.add(node); |
|
| 348 |
return node; |
|
| 349 |
} |
|
| 288 |
fun execute() |
|
| 289 |
{
|
|
| 290 |
when (mType) |
|
| 291 |
{
|
|
| 292 |
JOB_TYPE_VERTEX -> DistortedLibrary.adjustVertices(mTarget, mVertexEffects) |
|
| 293 |
JOB_TYPE_MATRIX -> mTarget.applyMatrix(mMatrixEffect, mAndAssoc, mEquAssoc) |
|
| 294 |
JOB_TYPE_MERGE_TEX -> mTarget.mergeTexComponentsNow() |
|
| 295 |
JOB_TYPE_MERGE_EFF -> mTarget.mergeEffComponentsNow() |
|
| 296 |
JOB_TYPE_JOIN -> mTarget.joinAttribs(mSource) |
|
| 297 |
JOB_TYPE_COPY -> mTarget.copy(mSource[0]) |
|
| 298 |
JOB_TYPE_TEXTURE -> mTarget.textureMap(mMaps, mComp) |
|
| 299 |
JOB_TYPE_ASSOC -> mTarget.setEffectAssociationNow(mComp, mAndAssoc, mEquAssoc) |
|
| 300 |
JOB_TYPE_CENTER -> mTarget.setComponentCenterNow(mComp, mX, mY, mZ) |
|
| 301 |
JOB_TYPE_ADD_EMPTY_TEX -> mTarget.addEmptyTexComponentNow() |
|
| 302 |
JOB_TYPE_NOT_AFFECTED -> mTarget.setNotAffectedComponentsNow(mComps) |
|
| 303 |
} |
|
| 304 |
} |
|
| 350 | 305 |
|
| 351 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 306 |
fun clear() |
|
| 307 |
{
|
|
| 308 |
mVertexEffects?.removeAll(false) |
|
| 309 |
} |
|
| 352 | 310 |
|
| 353 |
static JobNode copy(MeshBase target, MeshBase mesh) |
|
| 354 |
{
|
|
| 355 |
JobNode jn = mesh.mJobNode[0]; |
|
| 356 |
MeshBase[] meshes = new MeshBase[1]; |
|
| 357 |
meshes[0] = mesh; |
|
| 358 |
Job job = new Job(JOB_TYPE_COPY,target,meshes,null,null,null,0,0,0,0,0,0,null); |
|
| 359 |
JobNode node = new JobNode(job); |
|
| 360 |
node.mPrevJobs.add(jn); |
|
| 361 |
jn.mNextJobs.add(node); |
|
| 362 |
mJobs.add(node); |
|
| 363 |
return node; |
|
| 311 |
fun print(): String? |
|
| 312 |
{
|
|
| 313 |
when (mType) |
|
| 314 |
{
|
|
| 315 |
JOB_TYPE_VERTEX -> return "VERTEX" |
|
| 316 |
JOB_TYPE_MATRIX -> return "MATRIX" |
|
| 317 |
JOB_TYPE_MERGE_TEX -> return "MERGE_TEX" |
|
| 318 |
JOB_TYPE_MERGE_EFF -> return "MERGE_EFF" |
|
| 319 |
JOB_TYPE_JOIN -> return "JOIN" |
|
| 320 |
JOB_TYPE_COPY -> return "COPY" |
|
| 321 |
JOB_TYPE_TEXTURE -> return "TEXTURE" |
|
| 322 |
JOB_TYPE_ASSOC -> return "ASSOC" |
|
| 323 |
JOB_TYPE_CENTER -> return "CENTER" |
|
| 324 |
JOB_TYPE_ADD_EMPTY_TEX -> return "ADD_EMPTY_TEX" |
|
| 325 |
JOB_TYPE_NOT_AFFECTED -> return "POSTPROC COMPS" |
|
| 326 |
} |
|
| 327 |
|
|
| 328 |
return null |
|
| 329 |
} |
|
| 364 | 330 |
} |
| 365 | 331 |
|
| 366 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 367 |
|
|
| 368 |
static JobNode textureMap(MeshBase target, Static4D[] maps, int comp) |
|
| 332 |
////////////////////////////////////////////////////////////////////////// |
|
| 333 |
class JobNode(var mJob: Job?) |
|
| 369 | 334 |
{
|
| 370 |
JobNode jn = target.mJobNode[0]; |
|
| 371 |
Job job = new Job(JOB_TYPE_TEXTURE,target,null,null,null,maps,comp,0,0,0,0,0,null); |
|
| 372 |
JobNode node = new JobNode(job); |
|
| 373 |
node.mPrevJobs.add(jn); |
|
| 374 |
jn.mNextJobs.add(node); |
|
| 375 |
mJobs.add(node); |
|
| 376 |
return node; |
|
| 377 |
} |
|
| 335 |
var mPrevJobs: ArrayList<JobNode?>? |
|
| 336 |
var mNextJobs: ArrayList<JobNode?>? |
|
| 378 | 337 |
|
| 379 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 338 |
init |
|
| 339 |
{
|
|
| 340 |
mPrevJobs = ArrayList() |
|
| 341 |
mNextJobs = ArrayList() |
|
| 342 |
} |
|
| 380 | 343 |
|
| 381 |
static JobNode effectAssoc(MeshBase target, int comp, int andAssoc, int equAssoc) |
|
| 382 |
{
|
|
| 383 |
JobNode jn = target.mJobNode[0]; |
|
| 384 |
Job job = new Job(JOB_TYPE_ASSOC,target,null,null,null,null,comp,andAssoc,equAssoc,0,0,0,null); |
|
| 385 |
JobNode node = new JobNode(job); |
|
| 386 |
node.mPrevJobs.add(jn); |
|
| 387 |
jn.mNextJobs.add(node); |
|
| 388 |
mJobs.add(node); |
|
| 389 |
return node; |
|
| 390 |
} |
|
| 344 |
@Synchronized |
|
| 345 |
fun execute() |
|
| 346 |
{
|
|
| 347 |
if (mPrevJobs!=null) |
|
| 348 |
{
|
|
| 349 |
var node: JobNode? |
|
| 350 |
val numPrev = mPrevJobs!!.size |
|
| 351 |
|
|
| 352 |
for (i in 0 until numPrev) |
|
| 353 |
{
|
|
| 354 |
node = mPrevJobs!![0] // removeNode() rips the executed job out, thus the 0 |
|
| 355 |
node!!.execute() |
|
| 356 |
} |
|
| 357 |
|
|
| 358 |
removeNode(this) |
|
| 359 |
mJob!!.execute() |
|
| 360 |
} |
|
| 361 |
} |
|
| 391 | 362 |
|
| 392 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 363 |
@Synchronized |
|
| 364 |
fun clear() |
|
| 365 |
{
|
|
| 366 |
mPrevJobs!!.clear() |
|
| 367 |
mPrevJobs = null |
|
| 368 |
mNextJobs!!.clear() |
|
| 369 |
mNextJobs = null |
|
| 393 | 370 |
|
| 394 |
static JobNode componentCenter(MeshBase target, int comp, float x, float y, float z) |
|
| 395 |
{
|
|
| 396 |
JobNode jn = target.mJobNode[0]; |
|
| 397 |
Job job = new Job(JOB_TYPE_CENTER,target,null,null,null,null,comp,0,0,x,y,z,null); |
|
| 398 |
JobNode node = new JobNode(job); |
|
| 399 |
node.mPrevJobs.add(jn); |
|
| 400 |
jn.mNextJobs.add(node); |
|
| 401 |
mJobs.add(node); |
|
| 402 |
return node; |
|
| 403 |
} |
|
| 371 |
mJob!!.clear() |
|
| 372 |
mJob = null |
|
| 373 |
} |
|
| 404 | 374 |
|
| 405 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 375 |
fun print(level: Int) |
|
| 376 |
{
|
|
| 377 |
val numPrev = mPrevJobs!!.size |
|
| 378 |
val numNext = mNextJobs!!.size |
|
| 406 | 379 |
|
| 407 |
static JobNode setNotAffected(MeshBase target, int[] comps) |
|
| 408 |
{
|
|
| 409 |
JobNode jn = target.mJobNode[0]; |
|
| 410 |
Job job = new Job(JOB_TYPE_NOT_AFFECTED,target,null,null,null,null,0,0,0,0,0,0,comps); |
|
| 411 |
JobNode node = new JobNode(job); |
|
| 412 |
node.mPrevJobs.add(jn); |
|
| 413 |
jn.mNextJobs.add(node); |
|
| 414 |
mJobs.add(node); |
|
| 415 |
return node; |
|
| 416 |
} |
|
| 380 |
var str: String? = "" |
|
| 381 |
for (i in 0 until level) str += " " |
|
| 417 | 382 |
|
| 418 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 419 |
/** |
|
| 420 |
* Only for use by the library itself. |
|
| 421 |
* |
|
| 422 |
* @y.exclude |
|
| 423 |
*/ |
|
| 424 |
public static void onPause() |
|
| 425 |
{
|
|
| 426 |
int num = mJobs.size(); |
|
| 383 |
str += mJob!!.print() |
|
| 427 | 384 |
|
| 428 |
for(int i=0; i<num; i++) |
|
| 429 |
{
|
|
| 430 |
mJobs.get(i).clear(); |
|
| 431 |
} |
|
| 385 |
str += (" next: $numNext prev: $numPrev")
|
|
| 432 | 386 |
|
| 433 |
mJobs.clear(); |
|
| 387 |
DistortedLibrary.logMessage("DeferredJobs: $str")
|
|
| 388 |
|
|
| 389 |
for (i in 0 until numPrev) |
|
| 390 |
{
|
|
| 391 |
val node = mPrevJobs!![i] |
|
| 392 |
node!!.print(level+1) |
|
| 393 |
} |
|
| 394 |
} |
|
| 434 | 395 |
} |
| 435 |
} |
|
| 396 |
} |
|
| src/main/java/org/distorted/library/mesh/MeshBandedTriangle.kt | ||
|---|---|---|
| 18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
| 19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 20 | 20 |
|
| 21 |
package org.distorted.library.mesh;
|
|
| 21 |
package org.distorted.library.mesh |
|
| 22 | 22 |
|
| 23 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 24 |
|
|
| 25 |
import org.distorted.library.main.DistortedLibrary; |
|
| 23 |
import org.distorted.library.main.DistortedLibrary |
|
| 24 |
import kotlin.math.sqrt |
|
| 26 | 25 |
|
| 26 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 27 | 27 |
/** |
| 28 | 28 |
* Creator a triangular mesh divided into 'bands' i.e. strips parallel to one of the sides and |
| 29 | 29 |
* and of different elevations. |
| 30 |
* <p>
|
|
| 30 |
* |
|
| 31 | 31 |
* This is a building block for MeshMultigon. |
| 32 | 32 |
*/ |
| 33 |
public class MeshBandedTriangle extends MeshBase |
|
| 34 |
{
|
|
| 35 |
public static final int MODE_NORMAL = 0; |
|
| 36 |
public static final int MODE_INVERTED= 1; |
|
| 37 |
public static final int MODE_FLAT = 2; |
|
| 38 |
|
|
| 39 |
private static final int NUM_CACHE = 20; |
|
| 40 |
|
|
| 41 |
private float mLeftX, mLeftY; |
|
| 42 |
private float mRightX, mRightY; |
|
| 43 |
private float mTopX, mTopY; |
|
| 44 |
|
|
| 45 |
private float[] mNormL, mNormR; |
|
| 46 |
private int mMode; |
|
| 47 |
|
|
| 48 |
private float[] mBands; |
|
| 49 |
private int mNumBands; |
|
| 50 |
|
|
| 51 |
private int remainingVert; |
|
| 52 |
private int numVertices; |
|
| 53 |
private int extraBands, extraVertices; |
|
| 54 |
|
|
| 55 |
private float[] mCurveCache; |
|
| 56 |
private float mVecX, mVecY; |
|
| 57 |
|
|
| 58 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 59 |
|
|
| 60 |
private void computeNumberOfVertices() |
|
| 33 |
class MeshBandedTriangle : MeshBase |
|
| 34 |
{
|
|
| 35 |
private var mLeftX = 0f |
|
| 36 |
private var mLeftY = 0f |
|
| 37 |
private var mRightX = 0f |
|
| 38 |
private var mRightY = 0f |
|
| 39 |
private var mTopX = 0f |
|
| 40 |
private var mTopY = 0f |
|
| 41 |
|
|
| 42 |
private lateinit var mNormL: FloatArray |
|
| 43 |
private lateinit var mNormR: FloatArray |
|
| 44 |
private var mMode = 0 |
|
| 45 |
|
|
| 46 |
private lateinit var mBands: FloatArray |
|
| 47 |
private var mNumBands = 0 |
|
| 48 |
|
|
| 49 |
private var remainingVert = 0 |
|
| 50 |
override var numVertices: Int = 0 |
|
| 51 |
private var extraBands = 0 |
|
| 52 |
private var extraVertices = 0 |
|
| 53 |
|
|
| 54 |
private lateinit var mCurveCache: FloatArray |
|
| 55 |
private var mVecX = 0f |
|
| 56 |
private var mVecY = 0f |
|
| 57 |
|
|
| 58 |
companion object |
|
| 61 | 59 |
{
|
| 62 |
if( mMode==MODE_FLAT ) |
|
| 63 |
{
|
|
| 64 |
numVertices = 3; |
|
| 65 |
} |
|
| 66 |
else if( mMode==MODE_NORMAL ) |
|
| 67 |
{
|
|
| 68 |
numVertices = mNumBands*(mNumBands+2) + 4*extraVertices*extraBands; |
|
| 69 |
} |
|
| 70 |
else |
|
| 71 |
{
|
|
| 72 |
numVertices = mNumBands*(mNumBands+2); |
|
| 73 |
} |
|
| 74 |
|
|
| 75 |
remainingVert = numVertices; |
|
| 60 |
const val MODE_NORMAL: Int = 0 |
|
| 61 |
const val MODE_INVERTED: Int = 1 |
|
| 62 |
const val MODE_FLAT: Int = 2 |
|
| 63 |
|
|
| 64 |
private const val NUM_CACHE = 20 |
|
| 76 | 65 |
} |
| 66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 67 |
private fun computeNumberOfVertices() |
|
| 68 |
{
|
|
| 69 |
numVertices = if (mMode==MODE_FLAT) |
|
| 70 |
{
|
|
| 71 |
3 |
|
| 72 |
} |
|
| 73 |
else if (mMode==MODE_NORMAL) |
|
| 74 |
{
|
|
| 75 |
mNumBands*(mNumBands+2)+4*extraVertices*extraBands |
|
| 76 |
} |
|
| 77 |
else |
|
| 78 |
{
|
|
| 79 |
mNumBands*(mNumBands+2) |
|
| 80 |
} |
|
| 77 | 81 |
|
| 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 82 |
remainingVert = numVertices |
|
| 83 |
} |
|
| 79 | 84 |
|
| 80 |
private void computeCache() |
|
| 85 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 86 |
private fun computeCache() |
|
| 81 | 87 |
{
|
| 82 |
mCurveCache = new float[NUM_CACHE];
|
|
| 83 |
float[] tmpD = new float[mNumBands+1];
|
|
| 84 |
float[] tmpX = new float[mNumBands+1];
|
|
| 88 |
mCurveCache = FloatArray(NUM_CACHE)
|
|
| 89 |
val tmpD = FloatArray(mNumBands+1)
|
|
| 90 |
val tmpX = FloatArray(mNumBands+1)
|
|
| 85 | 91 |
|
| 86 |
for(int i=1; i<mNumBands; i++) |
|
| 87 |
{
|
|
| 88 |
tmpD[i] = (mBands[2*i-1]-mBands[2*i+1]) / (mBands[2*i]-mBands[2*i-2]); |
|
| 89 |
tmpX[i] = 1.0f - (mBands[2*i]+mBands[2*i-2])/2; |
|
| 90 |
} |
|
| 91 |
|
|
| 92 |
tmpD[0] = tmpD[1]; |
|
| 93 |
tmpD[mNumBands] = tmpD[mNumBands-1]; |
|
| 94 |
tmpX[0] = 0.0f; |
|
| 95 |
tmpX[mNumBands] = 1.0f; |
|
| 92 |
for (i in 1 until mNumBands) |
|
| 93 |
{
|
|
| 94 |
tmpD[i] = (mBands[2*i-1]-mBands[2*i+1])/(mBands[2*i]-mBands[2*i-2]) |
|
| 95 |
tmpX[i] = 1.0f-(mBands[2*i]+mBands[2*i-2])/2 |
|
| 96 |
} |
|
| 96 | 97 |
|
| 97 |
int prev = 0; |
|
| 98 |
int next = 0; |
|
| 98 |
tmpD[0] = tmpD[1] |
|
| 99 |
tmpD[mNumBands] = tmpD[mNumBands-1] |
|
| 100 |
tmpX[0] = 0.0f |
|
| 101 |
tmpX[mNumBands] = 1.0f |
|
| 99 | 102 |
|
| 100 |
for(int i=0; i<NUM_CACHE-1; i++) |
|
| 101 |
{
|
|
| 102 |
float x = i/(NUM_CACHE-1.0f); |
|
| 103 |
var prev = 0 |
|
| 104 |
var next = 0 |
|
| 103 | 105 |
|
| 104 |
if( x>=tmpX[next] )
|
|
| 106 |
for (i in 0 until NUM_CACHE-1)
|
|
| 105 | 107 |
{
|
| 106 |
prev = next; |
|
| 107 |
while( next<=mNumBands && x>=tmpX[next] ) next++; |
|
| 108 |
val x = i/(NUM_CACHE-1.0f) |
|
| 109 |
|
|
| 110 |
if (x>=tmpX[next]) |
|
| 111 |
{
|
|
| 112 |
prev = next |
|
| 113 |
while (next<=mNumBands&&x>=tmpX[next]) next++ |
|
| 114 |
} |
|
| 115 |
|
|
| 116 |
if (next>prev) |
|
| 117 |
{
|
|
| 118 |
val t = (x-tmpX[prev])/(tmpX[next]-tmpX[prev]) |
|
| 119 |
mCurveCache[i] = t*(tmpD[next]-tmpD[prev])+tmpD[prev] |
|
| 120 |
} |
|
| 121 |
else |
|
| 122 |
{
|
|
| 123 |
mCurveCache[i] = tmpD[next] |
|
| 124 |
} |
|
| 108 | 125 |
} |
| 109 | 126 |
|
| 110 |
if( next>prev ) |
|
| 127 |
mCurveCache[NUM_CACHE-1] = tmpD[mNumBands] |
|
| 128 |
} |
|
| 129 |
|
|
| 130 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 131 |
private fun derivative(x: Float): Float |
|
| 132 |
{
|
|
| 133 |
if (x>=1.0f) |
|
| 111 | 134 |
{
|
| 112 |
float t = (x-tmpX[prev]) / (tmpX[next]-tmpX[prev]); |
|
| 113 |
mCurveCache[i] = t*(tmpD[next]-tmpD[prev]) + tmpD[prev]; |
|
| 135 |
return 0.0f |
|
| 114 | 136 |
} |
| 115 |
else |
|
| 137 |
else
|
|
| 116 | 138 |
{
|
| 117 |
mCurveCache[i] = tmpD[next];
|
|
| 118 |
}
|
|
| 119 |
}
|
|
| 139 |
val tmp = x*(NUM_CACHE-1)
|
|
| 140 |
val i1 = tmp.toInt()
|
|
| 141 |
val i2 = i1+1
|
|
| 120 | 142 |
|
| 121 |
mCurveCache[NUM_CACHE-1] = tmpD[mNumBands]; |
|
| 122 |
} |
|
| 123 |
|
|
| 124 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 125 |
|
|
| 126 |
private float derivative(float x) |
|
| 127 |
{
|
|
| 128 |
if( x>=1.0f ) |
|
| 129 |
{
|
|
| 130 |
return 0.0f; |
|
| 131 |
} |
|
| 132 |
else |
|
| 133 |
{
|
|
| 134 |
float tmp = x*(NUM_CACHE-1); |
|
| 135 |
int i1 = (int)tmp; |
|
| 136 |
int i2 = i1+1; |
|
| 137 |
|
|
| 138 |
// why 0.5? Arbitrarily; this way the cubit faces of Twisty Puzzles |
|
| 139 |
// [the main and only user of this class] look better. |
|
| 140 |
return 0.5f*((tmp-i1)*(mCurveCache[i2]-mCurveCache[i1]) + mCurveCache[i1]); |
|
| 141 |
} |
|
| 143 |
// why 0.5? Arbitrarily; this way the cubit faces of Twisty Puzzles |
|
| 144 |
// [the main and only user of this class] look better. |
|
| 145 |
return 0.5f*((tmp-i1)*(mCurveCache[i2]-mCurveCache[i1])+mCurveCache[i1]) |
|
| 146 |
} |
|
| 142 | 147 |
} |
| 143 | 148 |
|
| 144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 145 |
|
|
| 146 |
private void figureOutNormalVector2D(float qx) |
|
| 149 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 150 |
private fun figureOutNormalVector2D(qx: Float) |
|
| 147 | 151 |
{
|
| 148 |
mVecX = mNormL[0] + qx*(mNormR[0]-mNormL[0]);
|
|
| 149 |
mVecY = mNormL[1] + qx*(mNormR[1]-mNormL[1]);
|
|
| 152 |
mVecX = mNormL[0]+qx*(mNormR[0]-mNormL[0])
|
|
| 153 |
mVecY = mNormL[1]+qx*(mNormR[1]-mNormL[1])
|
|
| 150 | 154 |
} |
| 151 | 155 |
|
| 152 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 153 |
|
|
| 154 |
private float figureOutDerivative(float qy) |
|
| 156 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 157 |
private fun figureOutDerivative(qy: Float): Float |
|
| 155 | 158 |
{
|
| 156 |
switch(mMode)
|
|
| 157 |
{
|
|
| 158 |
case MODE_NORMAL : return derivative(1-qy);
|
|
| 159 |
case MODE_INVERTED: return -derivative(qy);
|
|
| 160 |
default : return 0;
|
|
| 161 |
} |
|
| 159 |
return when (mMode)
|
|
| 160 |
{
|
|
| 161 |
MODE_NORMAL -> derivative(1-qy)
|
|
| 162 |
MODE_INVERTED -> -derivative(qy)
|
|
| 163 |
else -> 0f
|
|
| 164 |
}
|
|
| 162 | 165 |
} |
| 163 | 166 |
|
| 164 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 165 |
|
|
| 166 |
private float computeElevation(int band) |
|
| 167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 168 |
private fun computeElevation(band: Int): Float |
|
| 167 | 169 |
{
|
| 168 |
switch(mMode)
|
|
| 169 |
{
|
|
| 170 |
case MODE_NORMAL : return mBands[2*band+1];
|
|
| 171 |
case MODE_INVERTED: return mBands[2*(mNumBands-band)+1];
|
|
| 172 |
default : return mBands[2*mNumBands+1];
|
|
| 173 |
} |
|
| 170 |
return when (mMode)
|
|
| 171 |
{
|
|
| 172 |
MODE_NORMAL -> mBands[2*band+1]
|
|
| 173 |
MODE_INVERTED -> mBands[2*(mNumBands-band)+1]
|
|
| 174 |
else -> mBands[2*mNumBands+1]
|
|
| 175 |
}
|
|
| 174 | 176 |
} |
| 175 | 177 |
|
| 176 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 177 |
|
|
| 178 |
private int addStripVertex(int vertex, float qx, float qy, int band, float[] attribs1, float[] attribs2) |
|
| 178 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 179 |
private fun addStripVertex(vertex: Int, qx: Float, qy: Float, band: Int, attribs1: FloatArray, attribs2: FloatArray): Int |
|
| 179 | 180 |
{
|
| 180 |
remainingVert--;
|
|
| 181 |
remainingVert--
|
|
| 181 | 182 |
|
| 182 |
float bx = mLeftX + qx*(mRightX-mLeftX);
|
|
| 183 |
float by = mLeftY + qx*(mRightY-mLeftY);
|
|
| 183 |
val bx = mLeftX+qx*(mRightX-mLeftX)
|
|
| 184 |
val by = mLeftY+qx*(mRightY-mLeftY)
|
|
| 184 | 185 |
|
| 185 |
float q = 1-qy;
|
|
| 186 |
float x = bx + q*(mTopX-bx);
|
|
| 187 |
float y = by + q*(mTopY-by);
|
|
| 188 |
float z = computeElevation(band);
|
|
| 186 |
val q = 1-qy
|
|
| 187 |
val x = bx+q*(mTopX-bx)
|
|
| 188 |
val y = by+q*(mTopY-by)
|
|
| 189 |
val z = computeElevation(band)
|
|
| 189 | 190 |
|
| 190 |
figureOutNormalVector2D(band<mNumBands ? qx : 0.5f);
|
|
| 191 |
float d = figureOutDerivative(qy);
|
|
| 191 |
figureOutNormalVector2D(if (band<mNumBands) qx else 0.5f)
|
|
| 192 |
val d = figureOutDerivative(qy)
|
|
| 192 | 193 |
|
| 193 |
attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB ] = x;
|
|
| 194 |
attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y;
|
|
| 195 |
attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = z;
|
|
| 194 |
attribs1[VERT1_ATTRIBS*vertex+POS_ATTRIB ] = x
|
|
| 195 |
attribs1[VERT1_ATTRIBS*vertex+POS_ATTRIB+1] = y
|
|
| 196 |
attribs1[VERT1_ATTRIBS*vertex+POS_ATTRIB+2] = z
|
|
| 196 | 197 |
|
| 197 |
float vx = d*mVecX;
|
|
| 198 |
float vy = d*mVecY;
|
|
| 199 |
float vz = mVecX*mVecX + mVecY*mVecY;
|
|
| 200 |
float len = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
|
|
| 198 |
val vx = d*mVecX
|
|
| 199 |
val vy = d*mVecY
|
|
| 200 |
val vz = mVecX*mVecX+mVecY*mVecY
|
|
| 201 |
val len = sqrt((vx*vx+vy*vy+vz*vz).toDouble()).toFloat()
|
|
| 201 | 202 |
|
| 202 |
int index = VERT1_ATTRIBS*vertex + NOR_ATTRIB;
|
|
| 203 |
attribs1[index ] = vx/len;
|
|
| 204 |
attribs1[index+1] = vy/len;
|
|
| 205 |
attribs1[index+2] = vz/len;
|
|
| 203 |
val index: Int = VERT1_ATTRIBS*vertex+NOR_ATTRIB
|
|
| 204 |
attribs1[index] = vx/len
|
|
| 205 |
attribs1[index+1] = vy/len
|
|
| 206 |
attribs1[index+2] = vz/len
|
|
| 206 | 207 |
|
| 207 |
attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB ] = x+0.5f;
|
|
| 208 |
attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y+0.5f;
|
|
| 208 |
attribs2[VERT2_ATTRIBS*vertex+TEX_ATTRIB ] = x+0.5f
|
|
| 209 |
attribs2[VERT2_ATTRIBS*vertex+TEX_ATTRIB+1] = y+0.5f
|
|
| 209 | 210 |
|
| 210 |
return vertex+1;
|
|
| 211 |
return vertex+1
|
|
| 211 | 212 |
} |
| 212 | 213 |
|
| 213 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 214 |
|
|
| 215 |
private int createBand(int vertex, int band, float[] attribs1, float[] attribs2) |
|
| 214 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 215 |
private fun createBand(vert: Int, band: Int, attribs1: FloatArray, attribs2: FloatArray): Int |
|
| 216 | 216 |
{
|
| 217 |
boolean fromLeft = (band%2 == 0); |
|
| 218 |
int extra = ((band<extraBands && mMode==MODE_NORMAL) ? extraVertices : 0); |
|
| 219 |
int n = mNumBands-band-1; |
|
| 217 |
var vertex = vert |
|
| 218 |
val fromLeft = (band%2==0) |
|
| 219 |
val extra = (if ((band<extraBands&&mMode==MODE_NORMAL)) extraVertices else 0) |
|
| 220 |
val n = mNumBands-band-1 |
|
| 220 | 221 |
|
| 221 |
float b = 1.0f/(mNumBands-band);
|
|
| 222 |
float dxb = fromLeft ? b : -b;
|
|
| 223 |
float sdx = dxb/(extra+1);
|
|
| 222 |
val b = 1.0f/(mNumBands-band)
|
|
| 223 |
val dxb = if (fromLeft) b else -b
|
|
| 224 |
val sdx = dxb/(extra+1)
|
|
| 224 | 225 |
|
| 225 |
float qx = fromLeft ? 0.0f : 1.0f;
|
|
| 226 |
var qx = if (fromLeft) 0.0f else 1.0f
|
|
| 226 | 227 |
|
| 227 |
int bb = mMode==MODE_NORMAL ? band : mNumBands-band;
|
|
| 228 |
int bt = mMode==MODE_NORMAL ? band+1 : mNumBands-(band+1);
|
|
| 228 |
val bb = if (mMode==MODE_NORMAL) band else mNumBands-band
|
|
| 229 |
val bt = if (mMode==MODE_NORMAL) band+1 else mNumBands-(band+1)
|
|
| 229 | 230 |
|
| 230 |
float qyb = mBands[2*bb];
|
|
| 231 |
float qyt = mBands[2*bt];
|
|
| 231 |
var qyb = mBands[2*bb]
|
|
| 232 |
var qyt = mBands[2*bt]
|
|
| 232 | 233 |
|
| 233 |
if( mMode!=MODE_NORMAL ) |
|
| 234 |
{
|
|
| 235 |
qyb = 1-qyb; |
|
| 236 |
qyt = 1-qyt; |
|
| 237 |
} |
|
| 238 |
|
|
| 239 |
vertex = addStripVertex(vertex, qx, qyb, band, attribs1,attribs2); |
|
| 234 |
if (mMode!=MODE_NORMAL) |
|
| 235 |
{
|
|
| 236 |
qyb = 1-qyb |
|
| 237 |
qyt = 1-qyt |
|
| 238 |
} |
|
| 240 | 239 |
|
| 241 |
for(int v=0; v<extra; v++) |
|
| 242 |
{
|
|
| 243 |
vertex = addStripVertex(vertex, qx , qyt, band+1, attribs1,attribs2); |
|
| 244 |
vertex = addStripVertex(vertex, qx+(v+1)*sdx, qyb, band , attribs1,attribs2); |
|
| 245 |
} |
|
| 240 |
vertex = addStripVertex(vertex, qx, qyb, band, attribs1, attribs2) |
|
| 246 | 241 |
|
| 247 |
if( n>0 ) |
|
| 248 |
{
|
|
| 249 |
float t = 1.0f/n; |
|
| 250 |
float dxt = fromLeft ? t : -t; |
|
| 242 |
for (v in 0 until extra) |
|
| 243 |
{
|
|
| 244 |
vertex = addStripVertex(vertex, qx, qyt, band+1, attribs1, attribs2) |
|
| 245 |
vertex = addStripVertex(vertex, qx+(v+1)*sdx, qyb, band, attribs1, attribs2) |
|
| 246 |
} |
|
| 251 | 247 |
|
| 252 |
for(int v=0; v<n; v++)
|
|
| 248 |
if (n>0)
|
|
| 253 | 249 |
{
|
| 254 |
vertex=addStripVertex(vertex, qx+ v *dxt, qyt, band+1, attribs1, attribs2); |
|
| 255 |
vertex=addStripVertex(vertex, qx+(v+1)*dxb, qyb, band , attribs1, attribs2); |
|
| 250 |
val t = 1.0f/n |
|
| 251 |
val dxt = if (fromLeft) t else -t |
|
| 252 |
|
|
| 253 |
for (v in 0 until n) |
|
| 254 |
{
|
|
| 255 |
vertex = addStripVertex(vertex, qx+v*dxt, qyt, band+1, attribs1, attribs2) |
|
| 256 |
vertex = addStripVertex(vertex, qx+(v+1)*dxb, qyb, band, attribs1, attribs2) |
|
| 257 |
} |
|
| 256 | 258 |
} |
| 257 |
} |
|
| 258 | 259 |
|
| 259 |
qx = 1-qx;
|
|
| 260 |
qx = 1-qx
|
|
| 260 | 261 |
|
| 261 |
for(int v=0; v<=extra; v++)
|
|
| 262 |
{
|
|
| 263 |
vertex = addStripVertex(vertex, qx , qyt, band+1, attribs1,attribs2);
|
|
| 264 |
vertex = addStripVertex(vertex, qx-dxb+(v+1)*sdx, qyb, band , attribs1,attribs2);
|
|
| 265 |
} |
|
| 262 |
for (v in 0..extra)
|
|
| 263 |
{
|
|
| 264 |
vertex = addStripVertex(vertex, qx, qyt, band+1, attribs1, attribs2)
|
|
| 265 |
vertex = addStripVertex(vertex, qx-dxb+(v+1)*sdx, qyb, band, attribs1, attribs2)
|
|
| 266 |
}
|
|
| 266 | 267 |
|
| 267 |
return vertex;
|
|
| 268 |
return vertex
|
|
| 268 | 269 |
} |
| 269 | 270 |
|
| 270 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 271 |
|
|
| 272 |
private void buildGrid(float[] attribs1, float[] attribs2) |
|
| 271 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 272 |
private fun buildGrid(attribs1: FloatArray, attribs2: FloatArray) |
|
| 273 | 273 |
{
|
| 274 |
if( mMode==MODE_FLAT )
|
|
| 275 |
{
|
|
| 276 |
addStripVertex(0, 0, 1, 0, attribs1,attribs2);
|
|
| 277 |
addStripVertex(1, 0, 0, 0, attribs1,attribs2);
|
|
| 278 |
addStripVertex(2, 1, 1, 0, attribs1,attribs2);
|
|
| 279 |
} |
|
| 280 |
else |
|
| 281 |
{
|
|
| 282 |
int vertex=0;
|
|
| 283 |
for(int b=0; b<mNumBands; b++) vertex=createBand(vertex, b, attribs1, attribs2);
|
|
| 284 |
} |
|
| 274 |
if (mMode==MODE_FLAT)
|
|
| 275 |
{
|
|
| 276 |
addStripVertex(0, 0f, 1f, 0, attribs1, attribs2)
|
|
| 277 |
addStripVertex(1, 0f, 0f, 0, attribs1, attribs2)
|
|
| 278 |
addStripVertex(2, 1f, 1f, 0, attribs1, attribs2)
|
|
| 279 |
}
|
|
| 280 |
else
|
|
| 281 |
{
|
|
| 282 |
var vertex = 0
|
|
| 283 |
for (b in 0 until mNumBands) vertex = createBand(vertex, b, attribs1, attribs2)
|
|
| 284 |
}
|
|
| 285 | 285 |
} |
| 286 | 286 |
|
| 287 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 288 |
// PUBLIC API |
|
| 289 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 290 |
/** |
|
| 291 |
* Create a triangular mesh split into 'bands' - i.e. strips of triangles - which are parallel to |
|
| 292 |
* a given edge. |
|
| 293 |
* |
|
| 294 |
* @param vL A pair of floats (x,y) which defines the 'left' vertex of the triangle. |
|
| 295 |
* @param vR A pair of floats (x,y) which defines the 'right' vertex of the triangle. |
|
| 296 |
* @param vT A pair of floats (x,y) which defines the 'top' vertex of the triangle. |
|
| 297 |
* @param bands 2K floats; K pairs of two floats each describing a single band. |
|
| 298 |
* From (1.0,Z[0]) (the 'left-right' edge, its Z elevation) to (0.0,Z[K])
|
|
| 299 |
* (the 'top' vertex, its elevation). The polygon is split into such strips.
|
|
| 300 |
* Must be band[2*i] > band[2*(i+1)] !
|
|
| 301 |
* The way the bands get interpreted also depends on the 'mode' param.
|
|
| 302 |
* @param normL A pair of floats which define a 2D vector - which is the normal vector of each |
|
| 303 |
* mesh vertex which lies on the 'left-top' edge casted to the XY plane.
|
|
| 304 |
* @param normR Same as above but about the vertices which belong to the 'right-top' triangle |
|
| 305 |
* edge. This and the previous param define the vector field of normals, as seen
|
|
| 306 |
* from above, of the whole mesh.
|
|
| 307 |
* @param mode MODE_UP, MODE_DOWN or MODE_FLAT. |
|
| 308 |
* This defines how we interpret the bands.
|
|
| 309 |
* If UP, we interpret them the same as in MeshPolygon - i.e. the first band is
|
|
| 310 |
* about the 'left-right' edge, then progressively towards the 'top'.
|
|
| 311 |
* If DOWN, we turn the interpretation of the bands upside-down: it is the last
|
|
| 312 |
* band which defines the strip aong the 'left-right' edge.
|
|
| 313 |
* If FLAT, everything is flat anyway, so we disregard the bands and return a mesh
|
|
| 314 |
* with 3 vertices.
|
|
| 315 |
* @param exBands This and the next parameter describe how to make the mesh denser at the |
|
| 316 |
* 'left' and 'right' vertices. If e.g. exBands=3 and exVertices=2, then 3 triangles
|
|
| 317 |
* of the outermost band (and 2 triangles of the next band, and 1 triangle of the
|
|
| 318 |
* third band) get denser - the 3 triangles become 3+2 = 5.
|
|
| 319 |
* @param exVertices See above. |
|
| 320 |
*/ |
|
| 321 |
public MeshBandedTriangle(float[] vL, float[] vR, float[] vT, float[] bands, float[] normL, float[] normR, int mode, int exBands, int exVertices)
|
|
| 287 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
| 288 |
// PUBLIC API
|
|
| 289 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
| 290 |
/**
|
|
| 291 |
* Create a triangular mesh split into 'bands' - i.e. strips of triangles - which are parallel to
|
|
| 292 |
* a given edge.
|
|
| 293 |
*
|
|
| 294 |
* @param vL A pair of floats (x,y) which defines the 'left' vertex of the triangle.
|
|
| 295 |
* @param vR A pair of floats (x,y) which defines the 'right' vertex of the triangle.
|
|
| 296 |
* @param vT A pair of floats (x,y) which defines the 'top' vertex of the triangle.
|
|
| 297 |
* @param bands 2K floats; K pairs of two floats each describing a single band.
|
|
| 298 |
* From (1.0,Z[0]) (the 'left-right' edge, its Z elevation) to (0.0,Z[K])
|
|
| 299 |
* (the 'top' vertex, its elevation). The polygon is split into such strips.
|
|
| 300 |
* Must be band[2*i] > band[2*(i+1)] !
|
|
| 301 |
* The way the bands get interpreted also depends on the 'mode' param.
|
|
| 302 |
* @param normL A pair of floats which define a 2D vector - which is the normal vector of each
|
|
| 303 |
* mesh vertex which lies on the 'left-top' edge casted to the XY plane.
|
|
| 304 |
* @param normR Same as above but about the vertices which belong to the 'right-top' triangle
|
|
| 305 |
* edge. This and the previous param define the vector field of normals, as seen
|
|
| 306 |
* from above, of the whole mesh.
|
|
| 307 |
* @param mode MODE_UP, MODE_DOWN or MODE_FLAT.
|
|
| 308 |
* This defines how we interpret the bands.
|
|
| 309 |
* If UP, we interpret them the same as in MeshPolygon - i.e. the first band is
|
|
| 310 |
* about the 'left-right' edge, then progressively towards the 'top'.
|
|
| 311 |
* If DOWN, we turn the interpretation of the bands upside-down: it is the last
|
|
| 312 |
* band which defines the strip aong the 'left-right' edge.
|
|
| 313 |
* If FLAT, everything is flat anyway, so we disregard the bands and return a mesh
|
|
| 314 |
* with 3 vertices.
|
|
| 315 |
* @param exBands This and the next parameter describe how to make the mesh denser at the
|
|
| 316 |
* 'left' and 'right' vertices. If e.g. exBands=3 and exVertices=2, then 3 triangles
|
|
| 317 |
* of the outermost band (and 2 triangles of the next band, and 1 triangle of the
|
|
| 318 |
* third band) get denser - the 3 triangles become 3+2 = 5.
|
|
| 319 |
* @param exVertices See above.
|
|
| 320 |
*/
|
|
| 321 |
constructor(vL: FloatArray, vR: FloatArray, vT: FloatArray, bands: FloatArray, normL: FloatArray, normR: FloatArray, mode: Int, exBands: Int, exVertices: Int) : super()
|
|
| 322 | 322 |
{
|
| 323 |
super(); |
|
| 323 |
mLeftX = vL[0] |
|
| 324 |
mLeftY = vL[1] |
|
| 325 |
mRightX = vR[0] |
|
| 326 |
mRightY = vR[1] |
|
| 327 |
mTopX = vT[0] |
|
| 328 |
mTopY = vT[1] |
|
| 324 | 329 |
|
| 325 |
mLeftX = vL[0]; |
|
| 326 |
mLeftY = vL[1]; |
|
| 327 |
mRightX = vR[0]; |
|
| 328 |
mRightY = vR[1]; |
|
| 329 |
mTopX = vT[0]; |
|
| 330 |
mTopY = vT[1]; |
|
| 330 |
mMode = mode |
|
| 331 |
mNormL = floatArrayOf(normL[0], normL[1]) |
|
| 332 |
mNormR = floatArrayOf(normR[0], normR[1]) |
|
| 331 | 333 |
|
| 332 |
mMode = mode; |
|
| 333 |
mNormL= new float[] { normL[0],normL[1] };
|
|
| 334 |
mNormR= new float[] { normR[0],normR[1] };
|
|
| 334 |
mBands = bands |
|
| 335 |
mNumBands = mBands.size/2-1 |
|
| 336 |
extraBands = exBands |
|
| 337 |
extraVertices = exVertices |
|
| 335 | 338 |
|
| 336 |
mBands = bands; |
|
| 337 |
mNumBands = mBands.length/2 -1; |
|
| 338 |
extraBands = exBands; |
|
| 339 |
extraVertices = exVertices; |
|
| 339 |
computeNumberOfVertices() |
|
| 340 |
computeCache() |
|
| 340 | 341 |
|
| 341 |
computeNumberOfVertices();
|
|
| 342 |
computeCache();
|
|
| 342 |
val attribs1 = FloatArray(VERT1_ATTRIBS*numVertices)
|
|
| 343 |
val attribs2 = FloatArray(VERT2_ATTRIBS*numVertices)
|
|
| 343 | 344 |
|
| 344 |
float[] attribs1= new float[VERT1_ATTRIBS*numVertices]; |
|
| 345 |
float[] attribs2= new float[VERT2_ATTRIBS*numVertices]; |
|
| 345 |
buildGrid(attribs1, attribs2) |
|
| 346 | 346 |
|
| 347 |
buildGrid(attribs1,attribs2);
|
|
| 347 |
if (remainingVert!=0) DistortedLibrary.logMessage("MeshBandedTriangle: remainingVert $remainingVert")
|
|
| 348 | 348 |
|
| 349 |
if( remainingVert!=0 ) |
|
| 350 |
DistortedLibrary.logMessage("MeshBandedTriangle: remainingVert " +remainingVert );
|
|
| 351 |
|
|
| 352 |
setAttribs(attribs1,attribs2); |
|
| 349 |
setAttribs(attribs1, attribs2) |
|
| 353 | 350 |
} |
| 354 | 351 |
|
| 355 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 356 |
/** |
|
| 357 |
* Copy constructor. |
|
| 358 |
*/ |
|
| 359 |
public MeshBandedTriangle(MeshBandedTriangle mesh, boolean deep) |
|
| 360 |
{
|
|
| 361 |
super(mesh,deep); |
|
| 362 |
} |
|
| 363 |
|
|
| 364 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 365 |
/** |
|
| 366 |
* Copy the Mesh. |
|
| 367 |
* |
|
| 368 |
* @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices, |
|
| 369 |
* normals and inflates (the rest, in particular the mVertAttribs2 containing texture |
|
| 370 |
* coordinates and effect associations, is always deep copied) |
|
| 371 |
*/ |
|
| 372 |
public MeshBandedTriangle copy(boolean deep) |
|
| 352 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 353 |
/** |
|
| 354 |
* Copy constructor. |
|
| 355 |
*/ |
|
| 356 |
constructor(mesh: MeshBandedTriangle, deep: Boolean) : super(mesh, deep) |
|
| 357 |
|
|
| 358 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 359 |
/** |
|
| 360 |
* Copy the Mesh. |
|
| 361 |
* |
|
| 362 |
* @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices, |
|
| 363 |
* normals and inflates (the rest, in particular the mVertAttribs2 containing texture |
|
| 364 |
* coordinates and effect associations, is always deep copied) |
|
| 365 |
*/ |
|
| 366 |
override fun copy(deep: Boolean): MeshBandedTriangle |
|
| 373 | 367 |
{
|
| 374 |
return new MeshBandedTriangle(this,deep);
|
|
| 368 |
return MeshBandedTriangle(this, deep)
|
|
| 375 | 369 |
} |
| 376 |
} |
|
| 370 |
} |
|
| src/main/java/org/distorted/library/mesh/MeshBase.kt | ||
|---|---|---|
| 18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
| 19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 20 | 20 |
|
| 21 |
package org.distorted.library.mesh; |
|
| 22 |
|
|
| 23 |
import android.opengl.GLES30; |
|
| 24 |
|
|
| 25 |
import org.distorted.library.effect.MatrixEffect; |
|
| 26 |
import org.distorted.library.effect.VertexEffect; |
|
| 27 |
import org.distorted.library.effectqueue.EffectQueue; |
|
| 28 |
import org.distorted.library.main.DistortedLibrary; |
|
| 29 |
import org.distorted.library.main.InternalBuffer; |
|
| 30 |
import org.distorted.library.program.DistortedProgram; |
|
| 31 |
import org.distorted.library.type.Static4D; |
|
| 32 |
import org.distorted.library.uniformblock.UniformBlockAssociation; |
|
| 33 |
import org.distorted.library.uniformblock.UniformBlockCenter; |
|
| 34 |
|
|
| 35 |
import java.io.DataOutputStream; |
|
| 36 |
import java.io.IOException; |
|
| 37 |
import java.io.DataInputStream; |
|
| 38 |
import java.nio.ByteBuffer; |
|
| 39 |
import java.nio.ByteOrder; |
|
| 40 |
import java.nio.FloatBuffer; |
|
| 41 |
import java.util.ArrayList; |
|
| 21 |
package org.distorted.library.mesh |
|
| 22 |
|
|
| 23 |
import android.opengl.GLES30 |
|
| 24 |
import org.distorted.library.effect.MatrixEffect |
|
| 25 |
import org.distorted.library.effect.VertexEffect |
|
| 26 |
import org.distorted.library.effectqueue.EffectQueue |
|
| 27 |
import org.distorted.library.main.DistortedLibrary |
|
| 28 |
import org.distorted.library.main.InternalBuffer |
|
| 29 |
import org.distorted.library.program.DistortedProgram |
|
| 30 |
import org.distorted.library.type.Static4D |
|
| 31 |
import org.distorted.library.uniformblock.UniformBlockAssociation |
|
| 32 |
import org.distorted.library.uniformblock.UniformBlockCenter |
|
| 33 |
import java.io.DataInputStream |
|
| 34 |
import java.io.DataOutputStream |
|
| 35 |
import java.io.IOException |
|
| 36 |
import java.nio.ByteBuffer |
|
| 37 |
import java.nio.ByteOrder |
|
| 38 |
import kotlin.math.min |
|
| 39 |
import kotlin.math.sqrt |
|
| 42 | 40 |
|
| 43 | 41 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 44 | 42 |
/** |
| 45 | 43 |
* Abstract class which represents a Mesh, ie an array of vertices (rendered as a TRIANGLE_STRIP). |
| 46 |
* <p>
|
|
| 44 |
* |
|
| 47 | 45 |
* If you want to render to a particular shape, extend from here, construct a float array |
| 48 | 46 |
* containing per-vertex attributes, and call back setAttribs(). |
| 49 | 47 |
*/ |
| 50 |
public abstract class MeshBase |
|
| 51 |
{
|
|
| 52 |
private static final int ASSOC_UBO_BINDING = 3; |
|
| 53 |
private static final int CENTER_UBO_BINDING = 4; |
|
| 54 |
|
|
| 55 |
// sizes of attributes of an individual vertex. |
|
| 56 |
private static final int POS_DATA_SIZE= 3; // vertex coordinates: x,y,z |
|
| 57 |
private static final int NOR_DATA_SIZE= 3; // normal vector: x,y,z |
|
| 58 |
private static final int TEX_DATA_SIZE= 2; // texture coordinates: s,t |
|
| 59 |
private static final int COM_DATA_SIZE= 1; // component number, a single float |
|
| 60 |
|
|
| 61 |
static final int POS_ATTRIB = 0; |
|
| 62 |
static final int NOR_ATTRIB = POS_DATA_SIZE; |
|
| 63 |
static final int TEX_ATTRIB = 0; |
|
| 64 |
static final int COM_ATTRIB = TEX_DATA_SIZE; |
|
| 65 |
|
|
| 66 |
static final int VERT1_ATTRIBS= POS_DATA_SIZE + NOR_DATA_SIZE; // number of attributes of a vertex (the part changed by preapply) |
|
| 67 |
static final int VERT2_ATTRIBS= TEX_DATA_SIZE + COM_DATA_SIZE; // number of attributes of a vertex (the 'preapply invariant' part) |
|
| 68 |
static final int TRAN_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE; // number of attributes of a transform feedback vertex |
|
| 69 |
|
|
| 70 |
private static final int BYTES_PER_FLOAT = 4; |
|
| 71 |
|
|
| 72 |
private static final int OFFSET_POS = POS_ATTRIB*BYTES_PER_FLOAT; |
|
| 73 |
private static final int OFFSET_NOR = NOR_ATTRIB*BYTES_PER_FLOAT; |
|
| 74 |
private static final int OFFSET_TEX = TEX_ATTRIB*BYTES_PER_FLOAT; |
|
| 75 |
private static final int OFFSET_COM = COM_ATTRIB*BYTES_PER_FLOAT; |
|
| 76 |
|
|
| 77 |
private static final int TRAN_SIZE = TRAN_ATTRIBS*BYTES_PER_FLOAT; |
|
| 78 |
private static final int VERT1_SIZE = VERT1_ATTRIBS*BYTES_PER_FLOAT; |
|
| 79 |
private static final int VERT2_SIZE = VERT2_ATTRIBS*BYTES_PER_FLOAT; |
|
| 80 |
|
|
| 81 |
private static final int[] mCenterBlockIndex = new int[EffectQueue.MAIN_VARIANTS]; |
|
| 82 |
private static final int[] mAssocBlockIndex = new int[EffectQueue.MAIN_VARIANTS]; |
|
| 83 |
|
|
| 84 |
private static final int TEX_COMP_SIZE = 5; // 5 four-byte entities inside the component |
|
| 85 |
|
|
| 86 |
private static boolean mUseCenters; |
|
| 87 |
private static int mStride; |
|
| 88 |
private static int mMaxComponents = 100; |
|
| 89 |
|
|
| 90 |
private boolean mShowNormals; // when rendering this mesh, draw normal vectors? |
|
| 91 |
private InternalBuffer mVBO1, mVBO2, mTFO; // main vertex buffer and transform feedback buffer |
|
| 92 |
private int mNumVertices; |
|
| 93 |
private float[] mVertAttribs1; // packed: PosX,PosY,PosZ, NorX,NorY,NorZ |
|
| 94 |
private float[] mVertAttribs2; // packed: TexS,TexT, Component |
|
| 95 |
private float mInflate; |
|
| 96 |
private final UniformBlockAssociation mUBA; |
|
| 97 |
private UniformBlockCenter mUBC; |
|
| 98 |
private boolean mStrideCorrected; |
|
| 99 |
|
|
| 100 |
DeferredJobs.JobNode[] mJobNode; |
|
| 101 |
|
|
| 102 |
private static class TexComponent |
|
| 103 |
{
|
|
| 104 |
private int mEndIndex; |
|
| 105 |
private final Static4D mTextureMap; |
|
| 106 |
|
|
| 107 |
TexComponent(int end) |
|
| 108 |
{
|
|
| 109 |
mEndIndex = end; |
|
| 110 |
mTextureMap= new Static4D(0,0,1,1); |
|
| 111 |
} |
|
| 112 |
TexComponent(TexComponent original) |
|
| 113 |
{
|
|
| 114 |
mEndIndex = original.mEndIndex; |
|
| 115 |
|
|
| 116 |
float x = original.mTextureMap.get0(); |
|
| 117 |
float y = original.mTextureMap.get1(); |
|
| 118 |
float z = original.mTextureMap.get2(); |
|
| 119 |
float w = original.mTextureMap.get3(); |
|
| 120 |
mTextureMap = new Static4D(x,y,z,w); |
|
| 121 |
} |
|
Also available in: Unified diff
begin to migrate the 'mesh' package.