/**
* Copyright (C) 2013-2015 F(X)yz,
* Sean Phillips, Jason Pollastrini and Jose Pereda
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fxyz.shapes.primitives.helper;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.scene.shape.TriangleMesh;
import org.fxyz.geometry.Point3D;
/**
*
* @author jpereda
*/
public class MeshHelper {
private float[] points;
private float[] texCoords;
private int[] faces;
private int[] faceSmoothingGroups;
private float[] f;
public MeshHelper() {
}
public MeshHelper(TriangleMesh tm) {
this.points = tm.getPoints().toArray(points);
this.texCoords = tm.getTexCoords().toArray(texCoords);
this.faces = tm.getFaces().toArray(faces);
this.faceSmoothingGroups = tm.getFaceSmoothingGroups().toArray(faceSmoothingGroups);
this.f=new float[points.length/3];
}
public MeshHelper(float[] points, float[] texCoords, int[] faces, int[] faceSmoothingGroups) {
this.points = points;
this.texCoords = texCoords;
this.faces = faces;
this.faceSmoothingGroups = faceSmoothingGroups;
this.f=new float[points.length/3];
}
public MeshHelper(float[] points, float[] texCoords, int[] faces, int[] faceSmoothingGroups, float[] f) {
this.points = points;
this.texCoords = texCoords;
this.faces = faces;
this.faceSmoothingGroups = faceSmoothingGroups;
this.f=f;
}
public float[] getPoints() {
return points;
}
public void setPoints(float[] points) {
this.points = points;
}
public float[] getTexCoords() {
return texCoords;
}
public void setTexCoords(float[] texCoords) {
this.texCoords = texCoords;
}
public int[] getFaces() {
return faces;
}
public void setFaces(int[] faces) {
this.faces = faces;
}
public int[] getFaceSmoothingGroups() {
return faceSmoothingGroups;
}
public void setFaceSmoothingGroups(int[] faceSmoothingGroups) {
this.faceSmoothingGroups = faceSmoothingGroups;
}
public float[] getF() {
return f;
}
public void setF(float[] f) {
this.f = f;
}
/*
Add to the meshHelper a new meshHelper, to store the data of two
meshes that can be joined into one
*/
public void addMesh(MeshHelper mh){
int numPoints = points.length/3;
int numTexCoords = texCoords.length/2;
this.points = addFloatArray(points,mh.getPoints());
this.f = addFloatArray(f,mh.getF());
this.texCoords = addFloatArray(texCoords,mh.getTexCoords());
this.faces = addIntArray(faces,traslateFaces(mh.getFaces(),numPoints,numTexCoords));
this.faceSmoothingGroups = addIntArray(faceSmoothingGroups,mh.getFaceSmoothingGroups());
}
/*
Add to the meshHelper a list of meshHelpers, to store the data of several
meshes that can be joined into one
*/
public void addMesh(List<MeshHelper> mhs){
mhs.forEach(mh->{
int numPoints = points.length/3;
int numTexCoords = texCoords.length/2;
this.points = addFloatArray(points,mh.getPoints());
this.f = addFloatArray(f,mh.getF());
this.texCoords = addFloatArray(texCoords,mh.getTexCoords());
this.faces = addIntArray(faces,traslateFaces(mh.getFaces(),numPoints,numTexCoords));
this.faceSmoothingGroups = addIntArray(faceSmoothingGroups,mh.getFaceSmoothingGroups());
});
}
/*
Add to the meshHelper a new meshHelper, and given a list of new positions,
the data of a list of meshes on these locations will be created, to store the data of
these meshes that can be joined into one
*/
public void addMesh(MeshHelper mh, List<Point3D> traslate){
float[] newPoints = new float[points.length+mh.getPoints().length*traslate.size()];
float[] newF = new float[f.length+mh.getF().length*traslate.size()];
float[] newTexCoords = new float[texCoords.length+mh.getTexCoords().length*traslate.size()];
int[] newFaces = new int[faces.length+mh.getFaces().length*traslate.size()];
int[] newFaceSmoothingGroups = new int[faceSmoothingGroups.length+mh.getFaceSmoothingGroups().length*traslate.size()];
System.arraycopy(points, 0, newPoints, 0, points.length);
System.arraycopy(f, 0, newF, 0, f.length);
System.arraycopy(texCoords, 0, newTexCoords, 0, texCoords.length);
System.arraycopy(faces, 0, newFaces, 0, faces.length);
System.arraycopy(faceSmoothingGroups, 0, newFaceSmoothingGroups, 0, faceSmoothingGroups.length);
int numPoints = mh.getPoints().length;
int numF = mh.getF().length;
int numTexCoords = mh.getTexCoords().length;
int numFaces = mh.getFaces().length;
int numFaceSmoothingGroups = mh.getFaceSmoothingGroups().length;
AtomicInteger count=new AtomicInteger();
// List<float[]> collect = traslate.parallelStream().map(p3d->transform(mh.getPoints(),p3d)).collect(Collectors.toList());
traslate.forEach(p3d->{
System.arraycopy(transform(mh.getPoints(),p3d), 0, newPoints, points.length+numPoints*count.get(), mh.getPoints().length);
float[] ff=mh.getF();
Arrays.fill(ff,p3d.f);
System.arraycopy(ff, 0, newF, f.length+numF*count.get(), ff.length);
System.arraycopy(mh.getTexCoords(), 0, newTexCoords, texCoords.length+numTexCoords*count.get(), mh.getTexCoords().length);
System.arraycopy(traslateFaces(mh.getFaces(),numPoints/3*(count.get()+1),numTexCoords/2*(count.get()+1)), 0, newFaces, faces.length+numFaces*count.get(), mh.getFaces().length);
System.arraycopy(mh.getFaceSmoothingGroups(), 0, newFaceSmoothingGroups, faceSmoothingGroups.length+numFaceSmoothingGroups*count.getAndIncrement(), mh.getFaceSmoothingGroups().length);
});
points=newPoints;
f=newF;
texCoords=newTexCoords;
faces=newFaces;
faceSmoothingGroups=newFaceSmoothingGroups;
}
private int[] traslateFaces(int[] faces, int points, int texCoords){
int[] newFaces=new int[faces.length];
for(int i=0; i<faces.length; i++){
newFaces[i]=faces[i]+(i%2==0?points:texCoords);
}
return newFaces;
}
private int[] addIntArray(int[] array1, int[] array2){
int[] array1and2 = new int[array1.length + array2.length];
System.arraycopy(array1, 0, array1and2, 0, array1.length);
System.arraycopy(array2, 0, array1and2, array1.length, array2.length);
return array1and2;
}
private float[] addFloatArray(float[] array1, float[] array2){
float[] array1and2 = new float[array1.length + array2.length];
System.arraycopy(array1, 0, array1and2, 0, array1.length);
System.arraycopy(array2, 0, array1and2, array1.length, array2.length);
return array1and2;
}
private float[] transform(float[] points, Point3D p3d) {
float[] newPoints=new float[points.length];
for(int i=0; i<points.length/3; i++){
newPoints[3*i]=points[3*i]+p3d.x;
newPoints[3*i+1]=points[3*i+1]+p3d.y;
newPoints[3*i+2]=points[3*i+2]+p3d.z;
}
return newPoints;
}
}