import java.awt.*;
|
import java.util.Vector;
|
|
class BezierSurface extends Composite implements BezierElement, java.io.Serializable
|
{
|
static final long serialVersionUID = 3659371981955525551L;
|
|
BezierSurface()
|
{
|
this(7,7);
|
}
|
|
BezierSurface(int nx, int nz)
|
{
|
name = "BezierSurface";
|
|
ctrlPnts = new Composite();
|
|
//int nx = 8, nz = 8;
|
float fnx = nx, fnz = nz;
|
|
float incx = 3.0f/(nx+2);
|
float incz = 3.0f/(nz+2);
|
|
int m = 0;
|
for( float i=-1.5f; i<1.51; i+=incx, m++)
|
{
|
int n = 0;
|
for( float j=-1.5f; j<1.51; j+=incz, n++)
|
{
|
Sphere s = new Sphere(j,0,i);
|
s.handle = true;
|
s.name = "CP " + m + n;
|
ctrlPnts.addElement(s);
|
}
|
}
|
|
for (int i=0; i<nx; i+=1) // bezier = 3)
|
{
|
for (int j=0; j<nz; j+=1) // bezier = 3)
|
{
|
// Checker
|
//if (((i^j)&1) == 0)
|
// continue;
|
|
Composite tmp = new Composite();
|
|
for (int k=0; k<4; k++)
|
{
|
for (int l=0; l<4; l++)
|
{
|
tmp.addElement(ctrlPnts.get((i+k)*(nz+3) + j+l));
|
}
|
}
|
|
addChild(new BezierPatch(tmp, j/fnz, (j+1)/fnz, (nx - i - 1)/fnx, (nx - i)/fnx));
|
}
|
}
|
|
recalculate();
|
}
|
|
Object3D deepCopy()
|
{
|
BezierSurface l = new BezierSurface();
|
deepCopySelf(l);
|
return l;
|
}
|
|
void draw(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
// ((BezierSurface)parent.parent).currentHandle = (Sphere)this;
|
// parent.parent.recalculate();
|
recalculate();
|
|
super.draw(display, root, selected, blocked);
|
|
//if (IsSelected())
|
// ctrlPnts.draw(display, true);
|
}
|
|
void createEditWindow(GroupEditor callee, boolean newWindow)
|
{
|
if(newWindow)
|
objectUI = new BezierEditor(this, deepCopy(), callee);
|
else
|
objectUI = new BezierEditor(this, callee);
|
|
editWindow = objectUI.GetEditor();
|
}
|
|
void getBounds(cVector minima, cVector maxima, boolean xform)
|
{
|
//spline.getBounds(minima, maxima, true);
|
maxima.z = maxima.x;
|
minima.z = minima.x = -maxima.x;
|
if (xform)
|
transformBounds(minima, maxima);
|
}
|
|
boolean inside(double x, double y, double z, boolean xform)
|
{
|
assert false;
|
|
return false;
|
}
|
|
void draw(ClickInfo info, int level, boolean select)
|
{
|
cVector sample;
|
info.g.setColor(Color.black);
|
int nPoints = ctrlPnts.size();
|
|
for (int i=0; i < nPoints; i++)
|
{
|
sample = ((Sphere)ctrlPnts.get(i)).getCenter();
|
Point prev = new Point(0, 0);
|
Point curr = new Point(0, 0);
|
Rectangle dummy = new Rectangle();
|
calcHotSpot(sample, //info,
|
prev, dummy);
|
sample = ((Sphere)ctrlPnts.get(i)).getCenter();
|
calcHotSpot(sample, //info,
|
curr, dummy);
|
info.g.drawLine(prev.x, prev.y, curr.x, curr.y);
|
prev.x = curr.x;
|
prev.y = curr.y;
|
}
|
}
|
|
void drawEditHandles(//ClickInfo info,
|
int level)
|
{
|
clickInfo.g.setColor(Color.red);
|
int count = ctrlPnts.size();
|
for (int i=0; i < count; i++)
|
{
|
cVector p = ((Sphere)ctrlPnts.elementAt(i)).getCenter();
|
Rectangle spot = calcHotSpot(p); //, info);
|
clickInfo.g.fillRect(spot.x, spot.y, spot.width, spot.height);
|
}
|
|
}
|
|
boolean doEditClick(//ClickInfo info,
|
int level)
|
{
|
startX = clickInfo.x;
|
startY = clickInfo.y;
|
int nPoints = ctrlPnts.size();
|
hitSomething = false;
|
for (int i=0; i < nPoints; i++)
|
{
|
cVector p = ((Sphere)ctrlPnts.elementAt(i)).getCenter();
|
Rectangle r = calcHotSpot(p); //, info);
|
if (r.contains(clickInfo.x, clickInfo.y))
|
{
|
hitSomething = true;
|
hitIndex = i;
|
currentHandle = (Sphere)ctrlPnts.get(hitIndex);
|
LA.vecCopy(p, startVec);
|
}
|
}
|
|
return hitSomething;
|
}
|
|
void doEditDrag(ClickInfo info)
|
{
|
if (!hitSomething)
|
return;
|
cVector delta = LA.newVector(info.x - startX, startY - info.y, 0);
|
LA.xformDir(delta, info.camera.fromScreen, delta);
|
delta.x /= 100 * info.camera.SCALE / info.camera.Distance();
|
delta.y /= 100 * info.camera.SCALE / info.camera.Distance();
|
delta.z /= 100 * info.camera.SCALE / info.camera.Distance();
|
cVector p = ((Sphere)ctrlPnts.get(hitIndex)).getCenter();
|
LA.vecCopy(startVec, p);
|
LA.vecAdd(p, delta, p);
|
|
currentHandle = (Sphere)ctrlPnts.get(hitIndex);
|
currentHandle.refreshCenter(p);
|
|
recalculate();
|
|
currentHandle = null;
|
}
|
|
public void recalculate()
|
{
|
int nb = children.size();
|
for (int i=0; i<nb; i++)
|
{
|
BezierPatch child = (BezierPatch) children.reserve(i);
|
child.depth = depth;
|
// SPEED if (currentHandle == null || child.ctrlPnts.contains(currentHandle))
|
{
|
//System.out.println("RECAL " + currentHandle);
|
child.recalculate();
|
}
|
children.release(i);
|
}
|
//System.out.println();
|
|
super.recalculate();
|
}
|
|
/*
|
void recalculate()
|
{
|
float[] vertices = new float[4*4*3];
|
|
for( int i=0, i3=0; i<ctrlPnts.size(); i++, i3+=3 )
|
{
|
cVector v = ((Sphere)ctrlPnts.get(i)).getCenter();
|
vertices[i3] = (float)v.x;
|
vertices[i3+1] = (float)v.y;
|
vertices[i3+2] = (float)v.z;
|
System.out.println("vertices = " + vertices[i3] + " " + vertices[i3+1] + " " + vertices[i3+2]);
|
}
|
|
bRep = cBezier.GenPatch(vertices, depth);
|
|
if (!bRep.trimmed)
|
bRep.Trim(false, false);
|
|
super.recalculate();
|
}
|
*/
|
|
private static int startX;
|
private static int startY;
|
private static boolean hitSomething;
|
private static int hitIndex;
|
private static cVector startVec = new cVector();
|
|
Sphere currentHandle;
|
|
Composite ctrlPnts;
|
|
int depth = 2;
|
|
public int GetDepth()
|
{
|
return depth;
|
}
|
|
public void SetDepth(int d)
|
{
|
depth = d;
|
}
|
}
|