package jhpro.engine3d;
import java.awt.Color;
import java.awt.Graphics;
import java.io.IOException;
public class OF_off implements Drawable
{
int nVerts;
int nFacets;
int nEdges;
static float vert[];
private int tvert[];
private int findex[];
static Facet facet[];
private FacetedObject fo;
static final Vec surfaceNormalOriginal;
static Vec surfaceNormalCurrent = null;
static int nFacets_static_copy = 0;
static boolean readyForShading = false;
private Volume boundingVolume;
private String modelFilename;
static double illuminationFactor = 1.0D;
static double ambientLight = 0.5D;
// static Color dyColor = new Color(255, 128, 128);
static private boolean isShading=true;
static
{
surfaceNormalOriginal = Vec.x_direction;
}
OF_off()
{
nVerts = 0;
nEdges = 0;
nFacets = 0;
vert = null;
}
OF_off(FacetedObject fo)
{
this.fo=fo;
isShading=this.fo.getShading();
fo.describe();
prepObject();
fo = null;
// System.out.println("Read done ... prepping ... done ");
modelFilename = "custom";
};
/**
* Generate object using its name
*
* @param modelName
*/
OF_off(String modelName)
{
this();
modelFilename = modelName;
try
{
System.out.println("Read-ing : \"" + modelName + "\" ");
if(modelName.endsWith(".off"))
fo = FileParse.readOffObject(modelName);
else
fo = FileParse.readNffObject(modelName);
// System.out.println("Read done ... prepping ... ");
fo.describe();
prepObject();
fo = null;
// System.out.println("Read done ... prepping ... done ");
}
catch(IOException e)
{
System.err.println("Error: " + e);
}
}
private static Vec vecFromIndex(int pi)
{
return new Vec(vert[pi], vert[pi + 1], vert[pi + 2]);
}
private static void calculateFacetNormals()
{
// int SamplesModal = Math.max(1, nFacets_static_copy / 10);
// System.out.println("Surface Normals: ");
for(int i = 0; i < nFacets_static_copy; i++)
{
Vec a = vecFromIndex(facet[i].index[0]);
Vec b = vecFromIndex(facet[i].index[1]);
Vec c = vecFromIndex(facet[i].index[2]);
Vec ba = Vec.sub(b, a);
Vec ca = Vec.sub(c, a);
facet[i].normal = Vec.cross(ba, ca).uvec();
// if(i % SamplesModal == 0)
// System.out.println((100 * i) / nFacets_static_copy + " % " + facet[i].normal.toString());
}
readyForShading = true;
}
private void prepObject()
{
nVerts = fo.v;
nFacets = fo.f;
nFacets_static_copy = nFacets;
nEdges = fo.e;
vert = new float[nVerts * 3];
facet = new Facet[nFacets];
findex = new int[nFacets];
for(int i = 0; i < nFacets; i++)
findex[i] = i;
int i,j;
for(i = j = 0; i < nVerts; i++)
{
vert[j++] = (float)fo.verticies[i][0];
vert[j++] = (float)fo.verticies[i][1];
vert[j++] = (float)fo.verticies[i][2];
}
for(i = 0; i < nFacets; i++)
{
facet[i] = new Facet(fo.n);
for(j = 0; j < fo.n; j++)
facet[i].index[j] = 3 * fo.vindex[i][j];
}
if(fo.getShading())
calculateFacetNormals();
}
public static void tranformNormal(Matrix3d mat)
{
double toDegrees = 57.295779513082323D;
Vec toLight = new Vec(1, 0, -1);
toLight.normalize();
surfaceNormalCurrent = mat.transformPoint(surfaceNormalOriginal);
double cosVal;
if(isShading)
{
if(!readyForShading)
calculateFacetNormals();
for(int i = 0; i < nFacets_static_copy; i++)
{
Vec snc = mat.transformPoint(facet[i].normal);
cosVal = Vec.dot(snc, toLight);
illuminationFactor = Math.min(1.0D, Math.pow(Math.abs(cosVal), 3D) + ambientLight);
facet[i].illuminationFactor = (float)illuminationFactor;
}
}
surfaceNormalCurrent.uvec();
cosVal = Vec.dot(surfaceNormalCurrent, toLight);
if(cosVal > 1.0D)
cosVal = 1.0D;
if(cosVal < -1D)
cosVal = -1D;
illuminationFactor = Math.min(1.0D, Math.abs(cosVal) + ambientLight);
// double acosVal = Math.acos(cosVal);
// int angle = (int)Math.round(acosVal * toDegrees);
}
public void transform(Matrix3d mat)
{
if(nVerts <= 0)
return;
if(tvert == null)
tvert = new int[nVerts * 3];
mat.transform_for_off(vert, tvert, nVerts);
}
void qs(int left, int right)
{
int i = left;
int j = right;
int x = facet[findex[(left + right) / 2]].zdepth;
do
{
while(facet[findex[i]].zdepth > x && i < right)
i++;
for(; x > facet[findex[j]].zdepth && j > left; j--);
if(i <= j)
{
int y = findex[i];
findex[i] = findex[j];
findex[j] = y;
i++;
j--;
}
} while(i <= j);
if(left < j)
qs(left, j);
if(i < right)
qs(i, right);
}
public synchronized void Paint(Graphics g)
{
int MAX_VERTS = 7;
int vx[] = new int[MAX_VERTS];
int vy[] = new int[MAX_VERTS];
g.setColor(fo.getPenColor());
if(vert == null || nVerts <= 0)
return;
if(fo.getSolidRendering())
{
for(int i = 0; i < nFacets; i++)
{
int average_depth = 0;
for(int c = 0; c < facet[i].nVerts; c++)
average_depth += tvert[facet[i].index[c] + 2];
facet[i].zdepth = average_depth / facet[i].nVerts;
}
qs(0, nFacets - 1);
}
for(int f = 0; f < nFacets; f++)
{
int i = findex[f];
int uglyFudge = 1;
for(int c = 0; c < facet[i].nVerts; c++)
{
vx[c] = tvert[facet[i].index[c]];
vy[c] = tvert[facet[i].index[c] + 1];
}
int c = facet[i].nVerts;
vx[c] = tvert[facet[i].index[0]];
vy[c] = tvert[facet[i].index[0] + 1];
int fvts = facet[i].nVerts;
if(fo.getSolidRendering())
{
g.setColor(fo.getFillColor());
if(isShading)
{
int gv = (int)(255F * facet[i].illuminationFactor);
// a better color
g.setColor(new Color(0, gv, gv,fo.getTransperancy()));
// gray color
// g.setColor(new Color(gv, gv, gv));
}
g.fillPolygon(vx, vy, fvts);
// g.setColor(Color.black);
g.setColor(fo.getPenColor()); // pen color
g.drawPolygon(vx, vy, fvts + uglyFudge);
} else
{
g.drawPolygon(vx, vy, fvts + uglyFudge);
}
}
}
public Volume getVolume()
{
return boundingVolume;
}
public Volume determineBoundingBox()
{
boundingVolume = Volume.determineBoundingBox(vert, nVerts);
return boundingVolume;
}
public String toString()
{
String s = "File: \"" + modelFilename + "\" has: \n " + nVerts + " verticies " + nEdges + " edges " + nFacets + " facets ";
return s;
}
}
Ads help maintain this website.