Revision 1b85f172
Added by Leszek Koltunski about 3 years ago
src/main/java/org/distorted/examples/meshfile/FactoryCubit.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
package org.distorted.examples.meshfile; |
21 | 21 |
|
22 |
import org.distorted.library.effect.MatrixEffect; |
|
23 |
import org.distorted.library.effect.MatrixEffectMove; |
|
24 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
|
25 |
import org.distorted.library.effect.MatrixEffectScale; |
|
22 | 26 |
import org.distorted.library.effect.VertexEffect; |
23 | 27 |
import org.distorted.library.effect.VertexEffectDeform; |
24 |
import org.distorted.library.effect.VertexEffectMove; |
|
25 |
import org.distorted.library.effect.VertexEffectQuaternion; |
|
26 |
import org.distorted.library.effect.VertexEffectScale; |
|
27 | 28 |
import org.distorted.library.mesh.MeshBase; |
28 | 29 |
import org.distorted.library.mesh.MeshJoined; |
29 | 30 |
import org.distorted.library.mesh.MeshPolygon; |
... | ... | |
37 | 38 |
|
38 | 39 |
class FactoryCubit |
39 | 40 |
{ |
40 |
static final float SQ5 = (float)Math.sqrt(5); |
|
41 |
static final float SIN18 = (SQ5-1)/4; |
|
42 |
static final float COS18 = (float)(0.25f*Math.sqrt(10.0f+2.0f*SQ5)); |
|
43 |
|
|
44 | 41 |
private static final float[] mBuffer = new float[3]; |
45 | 42 |
private static final float[] mQuat1 = new float[4]; |
46 | 43 |
private static final float[] mQuat2 = new float[4]; |
... | ... | |
50 | 47 |
|
51 | 48 |
private static FactoryCubit mThis; |
52 | 49 |
|
53 |
private static class FaceInfo
|
|
50 |
private static class StickerInfo
|
|
54 | 51 |
{ |
55 | 52 |
float[] vertices; |
53 |
} |
|
54 |
|
|
55 |
private static class FaceInfo |
|
56 |
{ |
|
57 |
int sticker; |
|
56 | 58 |
float vx,vy,vz; |
57 | 59 |
float scale; |
58 | 60 |
float qx,qy,qz,qw; |
59 | 61 |
boolean flip; |
60 | 62 |
} |
61 | 63 |
|
62 |
private static final ArrayList<FaceInfo> mFaceInfo = new ArrayList<>(); |
|
64 |
private static final ArrayList<FaceInfo> mFaceInfo = new ArrayList<>(); |
|
65 |
private static final ArrayList<StickerInfo> mStickerInfo = new ArrayList<>(); |
|
63 | 66 |
|
64 | 67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
65 | 68 |
|
... | ... | |
189 | 192 |
|
190 | 193 |
private void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius) |
191 | 194 |
{ |
192 |
Static4D reg= new Static4D(0,0,0,regionRadius); |
|
195 |
Static4D region= new Static4D(0,0,0,regionRadius);
|
|
193 | 196 |
|
194 | 197 |
float centX = center.get0(); |
195 | 198 |
float centY = center.get1(); |
... | ... | |
201 | 204 |
float y = strength*(centY - vertex.get1()); |
202 | 205 |
float z = strength*(centZ - vertex.get2()); |
203 | 206 |
|
204 |
VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg); |
|
207 |
VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, region);
|
|
205 | 208 |
mesh.apply(effect); |
206 | 209 |
} |
207 | 210 |
} |
... | ... | |
229 | 232 |
|
230 | 233 |
float A = (float)Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) ); |
231 | 234 |
|
232 |
//android.util.Log.e("D", "("+x1+","+y1+","+z1+") , ("+x2+","+y2+","+z2+") , ("+x3+","+y3+","+z3+")" ); |
|
233 |
|
|
234 |
//boolean result = (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z); |
|
235 |
|
|
236 |
//android.util.Log.e("D", "are those colinear? : "+result); |
|
237 |
|
|
238 | 235 |
return (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z); |
239 | 236 |
} |
240 | 237 |
|
... | ... | |
268 | 265 |
mBuffer[0] /= len; |
269 | 266 |
mBuffer[1] /= len; |
270 | 267 |
mBuffer[2] /= len; |
271 |
|
|
272 |
//android.util.Log.e("D", " normal: "+mBuffer[0]+" "+mBuffer[1]+" "+mBuffer[2]); |
|
273 | 268 |
} |
274 | 269 |
|
275 | 270 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
316 | 311 |
info.scale = Math.max(maxX-minX,maxY-minY); |
317 | 312 |
|
318 | 313 |
int len = vert3D.length; |
319 |
info.vertices = new float[2*len]; |
|
314 |
StickerInfo sInfo = new StickerInfo(); |
|
315 |
sInfo.vertices = new float[2*len]; |
|
316 |
mStickerInfo.add(sInfo); |
|
320 | 317 |
|
321 | 318 |
for( int vertex=0; vertex<len; vertex++ ) |
322 | 319 |
{ |
323 |
info.vertices[2*vertex ] = vert3D[vertex][0] / info.scale;
|
|
324 |
info.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
|
|
320 |
sInfo.vertices[2*vertex ] = vert3D[vertex][0] / info.scale;
|
|
321 |
sInfo.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
|
|
325 | 322 |
} |
326 | 323 |
|
327 | 324 |
info.flip = false; |
... | ... | |
399 | 396 |
} |
400 | 397 |
|
401 | 398 |
float cosTheta = mBuffer[2]; |
402 |
//float sinTheta = axiLen / vecLen; |
|
403 |
|
|
404 | 399 |
float sinHalfTheta = (float)Math.sqrt(0.5f*(1-cosTheta)); |
405 | 400 |
float cosHalfTheta = (float)Math.sqrt(0.5f*(1+cosTheta)); |
406 | 401 |
|
... | ... | |
486 | 481 |
|
487 | 482 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
488 | 483 |
|
489 |
private void correctInfo(FaceInfo info, float[] rotatedVertices, int len, float[] originalVertices, float sin, float cos, boolean flip)
|
|
484 |
private void correctInfo(FaceInfo info, float scale, float sin, float cos, int oldSticker, boolean flip)
|
|
490 | 485 |
{ |
491 |
info.flip = flip;
|
|
486 |
mStickerInfo.remove(info.sticker);
|
|
492 | 487 |
|
493 |
System.arraycopy(originalVertices, 0, info.vertices, 0, 2*len); |
|
494 |
|
|
495 |
float scale = rotatedVertices[0]!=0.0f ? originalVertices[0]/rotatedVertices[0] : |
|
496 |
originalVertices[1]/rotatedVertices[1]; |
|
488 |
info.flip = flip; |
|
489 |
info.sticker = oldSticker; |
|
497 | 490 |
info.scale *= scale; |
498 | 491 |
|
499 | 492 |
mQuat1[0] = 0.0f; |
... | ... | |
516 | 509 |
|
517 | 510 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
518 | 511 |
|
519 |
private boolean foundVertex(FaceInfo info, float[] buffer, int len, boolean inverted, float[] vertices, float[] vert2D, float lenVert) |
|
512 |
private boolean foundVertex(FaceInfo info, float[] buffer, int len, float[] preVert, |
|
513 |
float[] newVert, float lenVert, int oldSticker, boolean inverted) |
|
520 | 514 |
{ |
521 | 515 |
for(int vertex=0; vertex<len; vertex++) |
522 | 516 |
{ |
523 |
float xR = vertices[2*vertex ];
|
|
524 |
float yR = vertices[2*vertex+1];
|
|
517 |
float xR = newVert[2*vertex ];
|
|
518 |
float yR = newVert[2*vertex+1];
|
|
525 | 519 |
float lenRotV = (float)Math.sqrt(xR*xR+yR*yR); |
526 |
float cos = computeCos(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
|
|
527 |
float sin = computeSin(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
|
|
520 |
float cos = computeCos(xR,yR,preVert[0],preVert[1], lenRotV, lenVert);
|
|
521 |
float sin = computeSin(xR,yR,preVert[0],preVert[1], lenRotV, lenVert);
|
|
528 | 522 |
|
529 |
rotateAllVertices(buffer,len,vertices,sin,cos);
|
|
523 |
rotateAllVertices(buffer,len,newVert,sin,cos);
|
|
530 | 524 |
|
531 |
if( isScaledVersionOf(buffer,vert2D,len) )
|
|
525 |
if( isScaledVersionOf(buffer,preVert,len) )
|
|
532 | 526 |
{ |
533 |
correctInfo(info,buffer,len,vert2D,sin,cos,inverted); |
|
527 |
float scale = preVert[0]!=0.0f ? buffer[0]/preVert[0] : buffer[1]/preVert[1]; |
|
528 |
correctInfo(info,scale,sin,cos,oldSticker,inverted); |
|
534 | 529 |
return true; |
535 | 530 |
} |
536 | 531 |
} |
... | ... | |
540 | 535 |
|
541 | 536 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
542 | 537 |
|
543 |
private boolean tryFindingRotation(final FaceInfo info, final float[] vert2D)
|
|
538 |
private boolean successfullyCollapsedStickers(final FaceInfo newInfo, final FaceInfo preInfo)
|
|
544 | 539 |
{ |
545 |
int len = vert2D.length/2; |
|
540 |
StickerInfo sNewInfo = mStickerInfo.get(newInfo.sticker); |
|
541 |
StickerInfo sPreInfo = mStickerInfo.get(preInfo.sticker); |
|
542 |
int len = sPreInfo.vertices.length; |
|
543 |
float[] newVert = sNewInfo.vertices; |
|
546 | 544 |
|
547 |
if( len == info.vertices.length/2 )
|
|
545 |
if( len == newVert.length )
|
|
548 | 546 |
{ |
549 |
float[] tmp1 = new float[2*len]; |
|
550 |
float lenVert = (float)Math.sqrt(vert2D[0]*vert2D[0] + vert2D[1]*vert2D[1]); |
|
551 |
if( foundVertex(info,tmp1,len,false,info.vertices,vert2D,lenVert) ) return true; |
|
552 |
float[] tmp2 = new float[2*len]; |
|
553 |
mirrorAllVertices(tmp2,len,info.vertices); |
|
554 |
if( foundVertex(info,tmp1,len,true ,tmp2 ,vert2D,lenVert) ) return true; |
|
547 |
int oldSticker = preInfo.sticker; |
|
548 |
float[] tmp1 = new float[len]; |
|
549 |
float lenVert = (float)Math.sqrt(newVert[0]*newVert[0] + newVert[1]*newVert[1]); |
|
550 |
if( foundVertex(newInfo, tmp1, len/2, sPreInfo.vertices, newVert, lenVert, oldSticker, false) ) return true; |
|
551 |
float[] tmp2 = new float[len]; |
|
552 |
mirrorAllVertices(tmp2,len/2,sPreInfo.vertices); |
|
553 |
if( foundVertex(newInfo, tmp1, len/2, tmp2 , newVert, lenVert, oldSticker, true ) ) return true; |
|
555 | 554 |
} |
556 | 555 |
|
557 | 556 |
return false; |
... | ... | |
580 | 579 |
private void prepareFaceInfo( final float[][] vertices, final int[][] indexes) |
581 | 580 |
{ |
582 | 581 |
mFaceInfo.clear(); |
582 |
mStickerInfo.clear(); |
|
583 | 583 |
|
584 | 584 |
int numFaces = indexes.length; |
585 |
FaceInfo info;
|
|
585 |
FaceInfo preInfo;
|
|
586 | 586 |
|
587 | 587 |
for(int face=0; face<numFaces; face++) |
588 | 588 |
{ |
... | ... | |
593 | 593 |
|
594 | 594 |
for(int previous=0; previous<face; previous++) |
595 | 595 |
{ |
596 |
info = mFaceInfo.get(previous); |
|
597 |
if( tryFindingRotation(newInfo,info.vertices) ) |
|
598 |
{ |
|
599 |
android.util.Log.e("D", "comparing face "+face+" to "+previous+" SUCCESS!!"); |
|
600 |
break; |
|
601 |
} |
|
596 |
preInfo = mFaceInfo.get(previous); |
|
597 |
if( successfullyCollapsedStickers(newInfo,preInfo) ) break; |
|
602 | 598 |
} |
603 | 599 |
|
604 | 600 |
mFaceInfo.add(newInfo); |
... | ... | |
607 | 603 |
|
608 | 604 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
609 | 605 |
|
610 |
private void printInfo(FaceInfo info) |
|
606 |
private void prepareAndRoundCorners(MeshBase mesh, float[][] vertices, int[][] vertIndexes, |
|
607 |
float[][] corners, int[] cornerIndexes ) |
|
611 | 608 |
{ |
612 |
android.util.Log.e("D", "vx="+info.vx+" vy="+info.vy+" vz="+info.vz); |
|
613 |
android.util.Log.e("D", "qx="+info.qx+" qy="+info.qy+" qz="+info.qz+" qw="+info.qw); |
|
614 |
android.util.Log.e("D", "scale="+info.scale); |
|
609 |
int numNeig, lenFV; |
|
610 |
int lenV = vertices.length; |
|
611 |
int[] verts = new int[2*(lenV-1)]; |
|
612 |
Static3D[] staticVert = new Static3D[1]; |
|
613 |
Static3D center = new Static3D(0,0,0); |
|
614 |
float cx, cy, cz; |
|
615 |
float[] singleV; |
|
615 | 616 |
|
616 |
String ver=""; |
|
617 |
for(int v=0; v<lenV; v++) |
|
618 |
{ |
|
619 |
// prepare verts[] |
|
620 |
numNeig = 0; |
|
617 | 621 |
|
618 |
int len = info.vertices.length/2; |
|
622 |
for (int[] vertIndex : vertIndexes) |
|
623 |
{ |
|
624 |
lenFV = vertIndex.length; |
|
619 | 625 |
|
620 |
for(int i =0; i<len; i++) |
|
626 |
for (int fv = 0; fv < lenFV; fv++) |
|
627 |
if (vertIndex[fv] == v) |
|
628 |
{ |
|
629 |
int prev = fv > 0 ? fv - 1 : lenFV - 1; |
|
630 |
int next = fv < lenFV - 1 ? fv + 1 : 0; |
|
631 |
|
|
632 |
verts[numNeig++] = vertIndex[prev]; |
|
633 |
verts[numNeig++] = vertIndex[next]; |
|
634 |
} |
|
635 |
} |
|
636 |
|
|
637 |
cx=cy=cz=0.0f; |
|
638 |
|
|
639 |
// from verts[] prepare center |
|
640 |
for(int n=0; n<numNeig; n++) |
|
641 |
{ |
|
642 |
singleV = vertices[verts[n]]; |
|
643 |
|
|
644 |
cx += singleV[0]; |
|
645 |
cy += singleV[1]; |
|
646 |
cz += singleV[2]; |
|
647 |
} |
|
648 |
center.set(cx/numNeig - vertices[v][0],cy/numNeig - vertices[v][1],cz/numNeig - vertices[v][2]); |
|
649 |
|
|
650 |
// round Corners |
|
651 |
staticVert[0] = new Static3D(vertices[v][0], vertices[v][1], vertices[v][2]); |
|
652 |
|
|
653 |
int corn = cornerIndexes[v]; |
|
654 |
float strength = corners[corn][0]; |
|
655 |
float radius = corners[corn][1]; |
|
656 |
|
|
657 |
roundCorners(mesh, center, staticVert, strength, radius); |
|
658 |
} |
|
659 |
} |
|
660 |
|
|
661 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
662 |
|
|
663 |
private void printStickerInfo() |
|
664 |
{ |
|
665 |
String ver=""; |
|
666 |
int stickers = mStickerInfo.size(); |
|
667 |
|
|
668 |
for(int s=0; s<stickers; s++) |
|
621 | 669 |
{ |
622 |
ver += ("("+info.vertices[2*i]+","+info.vertices[2*i+1]+") "); |
|
670 |
ver = ""; |
|
671 |
StickerInfo info = mStickerInfo.get(s); |
|
672 |
int len = info.vertices.length/2; |
|
673 |
|
|
674 |
for(int i =0; i<len; i++) |
|
675 |
{ |
|
676 |
ver += ("("+info.vertices[2*i]+","+info.vertices[2*i+1]+") "); |
|
677 |
} |
|
623 | 678 |
} |
624 | 679 |
|
625 | 680 |
android.util.Log.e("D", "vertices= "+ver); |
... | ... | |
627 | 682 |
|
628 | 683 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
629 | 684 |
|
630 |
MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes, final float[][] bands, final int[] bandIndexes) |
|
685 |
private void printFaceInfo(FaceInfo info) |
|
686 |
{ |
|
687 |
android.util.Log.e("D", "q=("+info.qx+", "+info.qy+", "+info.qz+", "+info.qw+") v=(" |
|
688 |
+info.vx+", "+info.vy+", "+info.vz+") scale="+info.scale+" sticker="+info.sticker); |
|
689 |
} |
|
690 |
|
|
691 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
692 |
|
|
693 |
MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes, |
|
694 |
final float[][] bands , final int[] bandIndexes, |
|
695 |
final float[][] corners , final int[] cornerIndexes) |
|
631 | 696 |
{ |
632 | 697 |
int EFFECTS_PER_FACE = 3; |
633 | 698 |
|
... | ... | |
636 | 701 |
int numFaces = vertIndexes.length; |
637 | 702 |
float[] band, bandsComputed; |
638 | 703 |
MeshBase[] meshes = new MeshBase[numFaces]; |
639 |
FaceInfo info; |
|
704 |
FaceInfo fInfo; |
|
705 |
StickerInfo sInfo; |
|
706 |
|
|
707 |
//printStickerInfo(); |
|
640 | 708 |
|
641 | 709 |
for(int face=0; face<numFaces; face++) |
642 | 710 |
{ |
643 |
info = mFaceInfo.get(face); |
|
711 |
fInfo = mFaceInfo.get(face); |
|
712 |
sInfo = mStickerInfo.get(fInfo.sticker); |
|
644 | 713 |
|
645 |
android.util.Log.d("D", "--------------"); |
|
646 |
printInfo(info); |
|
714 |
//printFaceInfo(fInfo); |
|
647 | 715 |
|
648 | 716 |
band = bands[bandIndexes[face]]; |
649 | 717 |
bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]); |
650 |
meshes[face] = new MeshPolygon(info.vertices,bandsComputed,(int)band[5],(int)band[6]);
|
|
718 |
meshes[face] = new MeshPolygon(sInfo.vertices,bandsComputed,(int)band[5],(int)band[6]);
|
|
651 | 719 |
meshes[face].setEffectAssociation(0,(1<<face),0); |
652 | 720 |
} |
653 | 721 |
|
654 | 722 |
MeshBase mesh = new MeshJoined(meshes); |
655 |
VertexEffect[] effects = new VertexEffect[EFFECTS_PER_FACE*numFaces];
|
|
723 |
MatrixEffect[] effects = new MatrixEffect[EFFECTS_PER_FACE*numFaces];
|
|
656 | 724 |
Static3D center = new Static3D(0,0,0); |
657 | 725 |
|
658 | 726 |
for(int face=0; face<numFaces; face++) |
659 | 727 |
{ |
660 | 728 |
int assoc = (1<<face); |
661 |
info = mFaceInfo.get(face);
|
|
729 |
fInfo = mFaceInfo.get(face);
|
|
662 | 730 |
|
663 |
Static3D move3D= new Static3D(info.vx,info.vy,info.vz);
|
|
664 |
Static3D scale = new Static3D(info.scale,info.scale, info.flip ? -info.scale : info.scale);
|
|
665 |
Static4D quat = new Static4D(info.qx,info.qy,info.qz,info.qw);
|
|
731 |
Static3D move3D= new Static3D(fInfo.vx,fInfo.vy,fInfo.vz);
|
|
732 |
Static3D scale = new Static3D(fInfo.scale,fInfo.scale, fInfo.flip ? -fInfo.scale : fInfo.scale);
|
|
733 |
Static4D quat = new Static4D(fInfo.qx,fInfo.qy,fInfo.qz,fInfo.qw);
|
|
666 | 734 |
|
667 |
effects[EFFECTS_PER_FACE*face ] = new VertexEffectScale(scale);
|
|
668 |
effects[EFFECTS_PER_FACE*face+1] = new VertexEffectQuaternion(quat,center);
|
|
669 |
effects[EFFECTS_PER_FACE*face+2] = new VertexEffectMove(move3D);
|
|
735 |
effects[EFFECTS_PER_FACE*face ] = new MatrixEffectScale(scale);
|
|
736 |
effects[EFFECTS_PER_FACE*face+1] = new MatrixEffectQuaternion(quat,center);
|
|
737 |
effects[EFFECTS_PER_FACE*face+2] = new MatrixEffectMove(move3D);
|
|
670 | 738 |
|
671 |
effects[EFFECTS_PER_FACE*face ].setMeshAssociation(assoc,-1);
|
|
672 |
effects[EFFECTS_PER_FACE*face+1].setMeshAssociation(assoc,-1);
|
|
673 |
effects[EFFECTS_PER_FACE*face+2].setMeshAssociation(assoc,-1);
|
|
739 |
mesh.apply(effects[EFFECTS_PER_FACE*face ],assoc,-1);
|
|
740 |
mesh.apply(effects[EFFECTS_PER_FACE*face+1],assoc,-1);
|
|
741 |
mesh.apply(effects[EFFECTS_PER_FACE*face+2],assoc,-1);
|
|
674 | 742 |
} |
675 | 743 |
|
676 |
for( VertexEffect effect : effects ) mesh.apply(effect);
|
|
744 |
prepareAndRoundCorners(mesh, vertices, vertIndexes, corners, cornerIndexes);
|
|
677 | 745 |
|
678 | 746 |
return mesh; |
679 | 747 |
} |
Also available in: Unified diff
Face cubit creation: progress: rounded corners