|
import com.bulletphysics.dynamics.DynamicsWorld;
|
|
import java.awt.*;
|
import java.util.Vector;
|
|
import javax.media.j3d.Transform3D;
|
import javax.media.opengl.GL;
|
import javax.vecmath.Vector3d;
|
|
import javax.imageio.ImageIO;
|
import java.awt.image.*;
|
|
import //weka.core.
|
matrix.Matrix;
|
|
import java.util.UUID;
|
|
//import net.sourceforge.sizeof.SizeOf;
|
public class Object3D extends Vector<Object3D> implements java.io.Serializable, iSendInfo //, aurelienribon.tweenengine.TweenAccessor<Object3D>
|
{
|
//static final long serialVersionUID = -607422624994562685L;
|
static final long serialVersionUID = 5022536242724664900L;
|
|
// Use GetUUID for backward compatibility with null.
|
private UUID uuid = UUID.randomUUID();
|
|
// TEMPORARY for versions. No need to be transient.
|
mocap.reader.BVHReader.BVHResult savebvh;
|
Object3D saveskeleton;
|
|
// FileObject
|
Object3D savefilecontent;
|
//
|
|
String skyboxname;
|
String skyboxext;
|
|
Object3D[] versionlist;
|
int versionindex = -1;
|
|
java.util.Hashtable<java.util.UUID, Object3D> versiontable; // = new java.util.Hashtable<java.util.UUID, Object3D>();
|
|
ScriptNode scriptnode;
|
|
void deepCopyNode(Object3D other)
|
{
|
other.skyboxname = skyboxname;
|
other.skyboxext = skyboxext;
|
|
if (toParent != null)
|
{
|
other.toParent = LA.newMatrix();
|
other.fromParent = LA.newMatrix();
|
LA.matCopy(toParent, other.toParent);
|
LA.matCopy(fromParent, other.fromParent);
|
if (toParentMarked != null)
|
{
|
other.toParentMarked = LA.newMatrix();
|
other.fromParentMarked = LA.newMatrix();
|
LA.matCopy(toParentMarked, other.toParentMarked);
|
LA.matCopy(fromParentMarked, other.fromParentMarked);
|
}
|
}
|
else
|
{
|
if (other.toParent == null)
|
// assert(other.toParent == null);
|
// new Exception().printStackTrace();
|
System.err.println("null parent: " + other);
|
}
|
|
/*
|
double ident[][] = LA.newMatrix();
|
if (bRep == null)
|
other.bRep = null;
|
else
|
other.bRep = new BoundaryRep(bRep, ident);
|
*/
|
// Really new...
|
//other.editWindow = null;
|
if (name == null)
|
other.name = null;
|
else
|
other.name = new String(name);
|
|
if (material != null)
|
{
|
other.material = new cMaterial(material);
|
} else
|
{
|
other.material = null;
|
}
|
|
other.GetTextures().name = GetTextures().name;
|
|
CopyExtraMaterial(other);
|
|
other.touched = touched;
|
other.softtouched = softtouched;
|
|
other.random = random;
|
other.link2master = link2master;
|
other.transformcount = transformcount;
|
other.marked = marked;
|
other.skip = skip;
|
other.count = count;
|
other.flipV = flipV;
|
other.live = live;
|
other.rewind = rewind;
|
other.hide = hide;
|
other.texres = texres;
|
other.speedup = speedup;
|
other.height = height;
|
other.depth = depth;
|
}
|
|
int VersionCount()
|
{
|
int count = 0;
|
|
if (versionlist != null)
|
for (int i = versionlist.length; --i >= 0;)
|
{
|
if (versionlist[i] != null)
|
count++;
|
}
|
|
return count;
|
}
|
|
void InitOthers()
|
{
|
if (projectedVertices == null || projectedVertices.length <= 2)
|
{
|
projectedVertices = new Object3D.cVector2[3];
|
}
|
for (int i = 0; i < 3; i++)
|
{
|
projectedVertices[i] = new cVector2(); // Others
|
}
|
projectedVertices[0].x = 100; // bump
|
projectedVertices[1].y = 1000; // punchthrough. only for png
|
}
|
|
void MinMax(cVector minima, cVector maxima)
|
{
|
for (int xyz = 0; xyz < 3; xyz++)
|
{
|
if (min.get(xyz) < minima.get(xyz))
|
{
|
minima.set(xyz, min.get(xyz));
|
}
|
if (max.get(xyz) > maxima.get(xyz))
|
{
|
maxima.set(xyz, max.get(xyz));
|
}
|
}
|
}
|
|
void WriteTo(java.io.Writer writer) throws Exception
|
{
|
}
|
|
float GetGround(cVector floor)
|
{
|
if (blockloop)
|
return 0;
|
|
if (fromParent != null)
|
{
|
LA.xformPos(floor, fromParent, floor);
|
}
|
|
float maxheight = Float.NEGATIVE_INFINITY;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
float g = child.GetGround(new cVector(floor));
|
if (g != Float.NEGATIVE_INFINITY)
|
{
|
if (maxheight < g)
|
maxheight = g;
|
}
|
blockloop = false;
|
}
|
|
if (bRep != null)
|
{
|
float g = bRep.GetGround(floor);
|
if (g != Float.NEGATIVE_INFINITY)
|
{
|
if (maxheight < g)
|
maxheight = g;
|
}
|
}
|
|
return maxheight;
|
}
|
|
// for overwrite
|
public static int GEOMETRY = 1, MATERIAL = 2, TRANSFORM = 4, NAME = 8, TEXTURE = 16, UV = 32, COLOR = 64;
|
// public static final int COLOR = 1, MATERIAL = 2, TEXTURE = 4, GEOMETRY = 8, TRANSFORM = 16, NAME = 32, UV = 64;
|
|
// transient boolean reduced; // for morph reduction
|
|
transient com.bulletphysics.linearmath.Transform cache; // for fast merge
|
transient com.bulletphysics.linearmath.Transform cache_1; // for fast merge
|
|
transient Object3D transientsupport; // for cloning
|
transient boolean transientlink2master;
|
|
void SaveSupports()
|
{
|
if (blockloop)
|
return;
|
|
transientsupport = support;
|
transientlink2master = link2master;
|
|
support = null;
|
link2master = false;
|
|
if (bRep != null)
|
{
|
bRep.SaveSupports();
|
}
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.SaveSupports();
|
blockloop = false;
|
}
|
}
|
|
void RestoreSupports()
|
{
|
if (blockloop)
|
return;
|
|
support = transientsupport;
|
link2master = transientlink2master;
|
transientsupport = null;
|
transientlink2master = false;
|
|
if (bRep != null)
|
{
|
bRep.RestoreSupports();
|
}
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.RestoreSupports();
|
blockloop = false;
|
}
|
}
|
|
boolean HasBigData()
|
{
|
if (blockloop)
|
return false;
|
|
if (bRep != null)
|
{
|
return true;
|
}
|
|
blockloop = true;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
if (child.HasBigData())
|
{
|
blockloop = false;
|
return true;
|
}
|
}
|
|
blockloop = false;
|
return false;
|
}
|
|
void ExtractBigData(java.util.Hashtable<java.util.UUID, Object3D> hashtable)
|
{
|
if (blockloop)
|
return;
|
|
Object3D o;
|
|
boolean isnew = false;
|
|
if (hashtable.containsKey(GetUUID()))
|
{
|
o = hashtable.get(GetUUID());
|
|
Grafreed.Assert(this.bRep == o.bRep);
|
//if (this.bRep != null)
|
// assert(this.bRep.support == o.transientrep);
|
if (this.support != null)
|
assert(this.support.bRep == o.transientrep);
|
}
|
else
|
{
|
isnew = true;
|
|
o = new Object3D("copy of " + this.name);
|
|
hashtable.put(GetUUID(), o);
|
}
|
|
//if (!blockloop)
|
{
|
blockloop = true;
|
|
for (int i=0; i<Size(); i++)
|
{
|
get(i).ExtractBigData(hashtable);
|
}
|
|
blockloop = false;
|
}
|
|
//if (isnew)
|
ExtractBigData(o);
|
}
|
|
void ExtractBigData(Object3D o)
|
{
|
//System.err.println("ExtractBigData : " + this + " --> " + o);
|
|
if (o.bRep != null)
|
Grafreed.Assert(o.bRep == this.bRep);
|
|
o.bRep = this.bRep;
|
// July 2019 if (this.bRep != null)
|
// {
|
// o.transientrep = this.bRep.support;
|
// o.bRep.support = null;
|
// }
|
o.selection = this.selection;
|
//o.versionlist = this.versionlist;
|
//o.versionindex = this.versionindex;
|
|
if (this.support != null)
|
{
|
if (o.transientrep != null)
|
Grafreed.Assert(o.transientrep == this.support.bRep);
|
|
o.transientrep = this.support.bRep;
|
this.support.bRep = null;
|
}
|
|
// o.support = this.support;
|
// o.fileparent = this.fileparent;
|
// if (this.bRep != null)
|
// o.bRep = this.bRep.support;
|
|
this.bRep = null;
|
// if (this.bRep != null)
|
// this.bRep.support = null;
|
// this.support = null;
|
// this.fileparent = null;
|
}
|
|
// Object3D GetObject(java.util.UUID uuid)
|
// {
|
// if (this.uuid.equals(uuid))
|
// return this;
|
//
|
// if (blockloop)
|
// return null;
|
//
|
// blockloop = true;
|
//
|
// for (int i=0; i<Size(); i++)
|
// {
|
// Object3D o = get(i).GetObject(uuid);
|
//
|
// if (o != null)
|
// return o;
|
// }
|
//
|
// blockloop = false;
|
//
|
// return null;
|
// }
|
|
transient boolean tag;
|
|
void TagObjects(Object3D o, boolean tag)
|
{
|
if (blockloop)
|
return;
|
|
o.tag = tag;
|
|
if (o == this)
|
return;
|
|
blockloop = true;
|
|
for (int i=0; i<Size(); i++)
|
{
|
get(i).TagObjects(o, tag);
|
}
|
|
blockloop = false;
|
}
|
|
boolean HasTags()
|
{
|
if (blockloop)
|
return false;
|
|
blockloop = true;
|
|
boolean hasTags = false;
|
|
for (int i=0; i<Size(); i++)
|
{
|
hasTags |= get(i).tag || get(i).HasTags();
|
|
if (hasTags)
|
break;
|
}
|
|
blockloop = false;
|
|
return hasTags;
|
}
|
|
void RestoreBigData(java.util.Hashtable<java.util.UUID, Object3D> hashtable)
|
{
|
if (blockloop)
|
return;
|
|
if (!hashtable.containsKey(GetUUID()))
|
return;
|
|
Object3D o = hashtable.get(GetUUID());
|
|
RestoreBigData(o);
|
|
blockloop = true;
|
|
//hashtable.remove(GetUUID());
|
|
for (int i=0; i<Size(); i++)
|
{
|
get(i).RestoreBigData(hashtable);
|
}
|
|
blockloop = false;
|
}
|
|
void RestoreBigData(Object3D o)
|
{
|
//System.err.println("RestoreBigData : " + this + " <-- " + o);
|
Grafreed.Assert(this.bRep == null);
|
|
this.bRep = o.bRep;
|
if (this.support != null && o.transientrep != null)
|
{
|
this.support.bRep = o.transientrep;
|
}
|
|
this.selection = o.selection;
|
|
//this.versionlist = o.versionlist;
|
//this.versionindex = o.versionindex;
|
// July 2019 if (this.bRep != null)
|
// this.bRep.support = o.transientrep;
|
// this.support = o.support;
|
// this.fileparent = o.fileparent;
|
}
|
|
// MOCAP SUPPORT
|
double tx,ty,tz,rx,ry,rz;
|
|
public static final int FIXED_AXES = 0, MOVING_AXES = 1;
|
public static final int RX = 0, RY = 1, RZ = 2; // for specifying rotation order
|
public static final int TX = 3, TY = 4, TZ = 5;
|
public static final int NO_NAME = -1, SMALL_NAME = 0, BIG_NAME = 1;
|
String _name;
|
int _index;
|
boolean _isRoot;
|
//boolean _isHip;
|
boolean _isBone;
|
// private Bone _parent;
|
// private Bone[] _children = new Bone[0];
|
// transient BoneGeom _boneGeom; // the displayed geometry of the bone/joint
|
// transient JointGeom _jointGeom;
|
// private Switch _textSwitch;
|
// transient TransformGroup _baseTransTG
|
// ,_transTG
|
// ,_baseRotTG
|
// ,_rotTG
|
// ,_invBaseRotTG
|
// ;
|
// Transform3D _t1 = new Transform3D();
|
// Transform3D _t2 = new Transform3D();
|
// Transform3D _transTF = new Transform3D();
|
// Transform3D _tworld = new Transform3D();
|
// Vector3d _trans = new Vector3d();
|
int[] _dof = new int[0]; // rotation order
|
int _numDOF = 0;
|
// boolean _translationEnabled = true; // translation can be switched off
|
// boolean _rotationEnabled = true; // rotation can be switched off
|
int _rotationType = FIXED_AXES; // Euler rotation type
|
// double _scale = 1d; // scale is applied to all translational components
|
// MOCAP SUPPORT
|
|
void SetDynamics(DynamicsWorld d)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
obj.SetDynamics(d);
|
}
|
|
blockloop = false;
|
}
|
|
void ResetDynamics(DynamicsWorld d)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
obj.ResetDynamics(d);
|
}
|
|
blockloop = false;
|
}
|
|
void ResetRandom()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
if (obj == null)
|
continue; // mars 2014
|
|
obj.ResetRandom();
|
}
|
|
blockloop = false;
|
}
|
|
/**
|
* Gets one or many values from the target object associated to the
|
* given tween type. It is used by the Tween Engine to determine starting
|
* values.
|
*
|
* @param target The target object of the tween.
|
* @param tweenType An integer representing the tween type.
|
* @param returnValues An array which should be modified by this method.
|
* @return The count of modified slots from the returnValues array.
|
*/
|
public int getValues(Object3D target, int tweenType, float[] returnValues)
|
{
|
// System.out.println("getValues " + target + " to " + this);
|
// new Exception().printStackTrace();
|
returnValues[0] = (float)toParent[3][0];
|
returnValues[1] = (float)toParent[3][1];
|
returnValues[2] = (float)toParent[3][2];
|
|
return 3;
|
}
|
|
/**
|
* This method is called by the Tween Engine each time a running tween
|
* associated with the current target object has been updated.
|
*
|
* @param target The target object of the tween.
|
* @param tweenType An integer representing the tween type.
|
* @param newValues The new values determined by the Tween Engine.
|
*/
|
public void setValues(Object3D target, int tweenType, float[] newValues)
|
{
|
// System.out.println("setValues " + target + " to " + newValues[0]);
|
// new Exception().printStackTrace();
|
toParent[3][0] = newValues[0];
|
toParent[3][1] = newValues[1];
|
toParent[3][2] = newValues[2];
|
}
|
|
|
String GetName()
|
{
|
if (name != null)
|
return name;
|
|
if (parent == null)
|
return "nullparent";
|
|
return parent.GetName() + "#";
|
}
|
|
boolean live = false;
|
transient boolean keepdontselect;
|
boolean dontselect = false;
|
boolean hide = false;
|
boolean link2master = false; // performs reset support/master at each frame
|
boolean marked = false; // animation node
|
boolean skip = false; // centroid issue
|
boolean skipmocap = false; // mocap data
|
|
boolean random = false;
|
boolean speedup = false;
|
boolean rewind = false;
|
|
// Option to sort triangles, e.g. for transparency.
|
boolean sort = false;
|
|
float NORMALPUSH = 0;
|
|
Object3D support;
|
|
Object3D GetObject()
|
{
|
return this;
|
}
|
|
void SortBySize()
|
{
|
boolean sorted = false;
|
|
while (!sorted)
|
{
|
sorted = true;
|
|
for (int i=0; i<Size()-1; i++)
|
{
|
Object3D obji = get(i);
|
Object3D objj = get(i+1);
|
|
if (obji.MemorySize() < objj.MemorySize())
|
{
|
set(i, objj);
|
set(i+1, obji);
|
|
sorted = false;
|
}
|
}
|
}
|
}
|
|
void SortByName()
|
{
|
boolean sorted = false;
|
|
while (!sorted)
|
{
|
sorted = true;
|
|
for (int i=0; i<Size()-1; i++)
|
{
|
Object3D obji = get(i);
|
Object3D objj = get(i+1);
|
|
if (obji.GetName().compareTo(objj.GetName()) > 0)
|
{
|
set(i, objj);
|
set(i+1, obji);
|
|
sorted = false;
|
}
|
}
|
}
|
}
|
|
transient int memorysize; // needs to be transient, dunno why
|
|
int MemorySize()
|
{
|
if (memorysize == 0)
|
{
|
try
|
{
|
Object3D obj = this;
|
|
Object3D parent = obj.parent;
|
obj.parent = null;
|
Object3D support = obj.support;
|
obj.support = null;
|
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(baos);
|
|
out.writeObject(obj);
|
|
obj.parent = parent;
|
obj.support = support;
|
|
memorysize = baos.toByteArray().length;
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
}
|
|
return memorysize;
|
}
|
|
void Slower()
|
{
|
maxcount *= 2;
|
transformcount *= 2;
|
|
Matrix m = new Matrix(fromParent);
|
Matrix sqm = m.sqrt();
|
fromParent = sqm.getArray();
|
|
m = new Matrix(toParent);
|
sqm = m.sqrt();
|
toParent = sqm.getArray();
|
}
|
|
void Faster()
|
{
|
if (maxcount > 1)
|
{
|
maxcount /= 2;
|
transformcount /= 2;
|
|
LA.matConcat(toParent, toParent, toParent);
|
LA.matConcat(fromParent, fromParent, fromParent);
|
}
|
}
|
|
void SwitchMark()
|
{
|
Object3D copy = this;
|
|
Camera parentcam = Globals.theRenderer.ManipCamera();
|
|
if (Globals.theRenderer.ManipCamera() == Globals.theRenderer.Cameras()[0])
|
{
|
parentcam = Globals.theRenderer.Cameras()[1];
|
}
|
|
if (Globals.theRenderer.ManipCamera() == Globals.theRenderer.Cameras()[1])
|
{
|
parentcam = Globals.theRenderer.Cameras()[0];
|
}
|
|
if (this == parentcam)
|
{
|
//assert(this instanceof Camera);
|
|
for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.xformPos(Globals.theRenderer.TargetLookAt(), parentcam.toParent, Globals.theRenderer.TargetLookAt());
|
}
|
|
copy.marked ^= true;
|
|
if (copy.marked)
|
{
|
copy.Mark();
|
} else
|
{
|
copy.Unmark();
|
}
|
|
copy.SwapMark();
|
|
if (this == parentcam)
|
{
|
//assert(this instanceof Camera);
|
|
for (int count = parentcam.GetTransformCount(); --count>=0;)
|
LA.xformPos(Globals.theRenderer.TargetLookAt(), parentcam.fromParent, Globals.theRenderer.TargetLookAt());
|
}
|
|
copy.Touch(); // display list issue
|
}
|
|
void Mark()
|
{
|
if (toParent == null)
|
{
|
toParent = LA.newMatrix();
|
fromParent = LA.newMatrix();
|
}
|
|
if (toParentMarked == null)
|
{
|
if (maxcount != 1)
|
{
|
//new Exception().printStackTrace();
|
}
|
|
toParentMarked = LA.newMatrix();
|
fromParentMarked = LA.newMatrix();
|
}
|
|
LA.matCopy(toParent, toParentMarked);
|
LA.matCopy(fromParent, fromParentMarked);
|
|
int loops = maxcount;
|
|
while (loops > 1)
|
{
|
Matrix m = new Matrix(fromParentMarked);
|
Matrix sqm = m.sqrt();
|
fromParentMarked = sqm.getArray();
|
|
m = new Matrix(toParentMarked);
|
sqm = m.sqrt();
|
toParentMarked = sqm.getArray();
|
|
loops >>= 1;
|
}
|
}
|
|
void Unmark()
|
{
|
Object3D copy = this;
|
if (copy.toParentMarked == null)
|
{
|
copy.toParentMarked = LA.newMatrix();
|
copy.fromParentMarked = LA.newMatrix();
|
|
LA.matCopy(copy.toParent, copy.toParentMarked);
|
LA.matCopy(copy.fromParent, copy.fromParentMarked);
|
|
int loops = copy.maxcount;
|
|
while (loops > 1)
|
{
|
LA.matConcat(copy.toParentMarked, copy.toParentMarked, copy.toParentMarked);
|
LA.matConcat(copy.fromParentMarked, copy.fromParentMarked, copy.fromParentMarked);
|
|
loops >>= 1;
|
}
|
}
|
}
|
|
void SwapMark()
|
{
|
double[][] tempmat = toParent;
|
toParent = toParentMarked;
|
toParentMarked = tempmat;
|
|
tempmat = fromParent;
|
fromParent = fromParentMarked;
|
fromParentMarked = tempmat;
|
}
|
|
// Mark again according to current position (transformcount).
|
void Remark()
|
{
|
if (globalTransform == null)
|
{
|
globalTransform = new double[4][4];
|
}
|
|
LA.matIdentity(globalTransform);
|
|
// if (link2master) // if !marked?
|
// {
|
// // PATCH for global reset
|
// maxcount = transformcount; // 1;
|
// }
|
|
int tcount = //maxcount; //
|
transformcount; // GetTransformCount();
|
|
if (tcount == 0)
|
tcount = 1;
|
|
for (int i=tcount; --i>=0;)
|
LA.matConcat(globalTransform, toParent, globalTransform);
|
LA.matCopy(globalTransform, toParent);
|
|
LA.matIdentity(globalTransform);
|
for (int i=tcount; --i>=0;)
|
LA.matConcat(globalTransform, fromParent, globalTransform);
|
LA.matCopy(globalTransform, fromParent);
|
|
transformcount = maxcount; // 1;
|
Mark(); //maxcount = 0;
|
SwapMark();
|
}
|
|
void Reset()
|
{
|
if (scriptnode != null)
|
{
|
scriptnode.Reset();
|
}
|
// Reset(false);
|
// }
|
//
|
// void Reset(boolean fromscript)
|
// {
|
// marde pour serialization de Texture
|
resetmaxcount();
|
resettransformcount();
|
resetstep();
|
|
if (!marked)
|
{
|
transformcount = 0; // may 2014
|
//ResetRecur();
|
return;
|
}
|
|
if (Globals.fromscript)
|
{
|
transformcount = 0;
|
return;
|
}
|
|
// if (hide)
|
// {
|
//// if (maxcount > 10)
|
//// maxcount /= 10;
|
//// else
|
//// assert(maxcount == 1);
|
// if (globalTransform == null)
|
// {
|
// globalTransform = new double[4][4];
|
// }
|
//
|
// LA.matIdentity(globalTransform);
|
//
|
// if (link2master)
|
// {
|
// // PATCH for global reset
|
// maxcount = transformcount; // 1;
|
// }
|
//
|
// int tcount = maxcount; // transformcount; // GetTransformCount();
|
//
|
// if (tcount == 0)
|
// tcount = 1;
|
//
|
// for (int i=tcount; --i>=0;)
|
// LA.matConcat(globalTransform, toParent, globalTransform);
|
// LA.matCopy(globalTransform, toParent);
|
//
|
// LA.matIdentity(globalTransform);
|
// for (int i=tcount; --i>=0;)
|
// LA.matConcat(globalTransform, fromParent, globalTransform);
|
// LA.matCopy(globalTransform, fromParent);
|
//
|
// transformcount = 1;
|
// maxcount = 0;
|
// }
|
// else
|
if (false) // link2master && fromParent != null)
|
{
|
maxcount *= 2;
|
|
//fromParent[0][0] = 33;
|
//fromParent[1][0] = 24;
|
//fromParent[0][1] = 48;
|
//fromParent[1][1] = 57;
|
|
Matrix m = new Matrix(fromParent);
|
Matrix sqm = m.sqrt();
|
fromParent = sqm.getArray();
|
|
m = new Matrix(toParent);
|
sqm = m.sqrt();
|
toParent = sqm.getArray();
|
|
// toParent[3][0] /= 2;
|
// toParent[3][1] /= 2;
|
// toParent[3][2] /= 2;
|
// fromParent[3][0] *= 2;
|
// fromParent[3][1] *= 2;
|
// fromParent[3][2] *= 2;
|
}
|
else
|
transformcount = 0;
|
}
|
|
void Forward()
|
{
|
// marde pour serialization de Texture
|
resetmaxcount();
|
resettransformcount();
|
resetstep();
|
|
transformcount = maxcount;
|
}
|
|
void Step()
|
{
|
// marde pour serialization de Texture
|
resetmaxcount();
|
resettransformcount();
|
resetstep();
|
|
if (!marked)
|
{
|
//StepRecur();
|
return;
|
}
|
|
// if (hide)
|
// {
|
// maxcount = 0; // *= 10;
|
// }
|
// else
|
if (false) // link2master && toParent != null)
|
{
|
maxcount /= 2;
|
|
LA.matConcat(toParent, toParent, toParent);
|
LA.matConcat(fromParent, fromParent, fromParent);
|
// LA.matInvert(toParent, fromParent);
|
|
// toParent[3][0] *= 2;
|
// toParent[3][1] *= 2;
|
// toParent[3][2] *= 2;
|
// fromParent[3][0] /= 2;
|
// fromParent[3][1] /= 2;
|
// fromParent[3][2] /= 2;
|
}
|
else
|
transformcount++;
|
}
|
|
int maxcount;
|
int transformcount;
|
int step;
|
|
void resetmaxcount()
|
{
|
}
|
|
void resettransformcount()
|
{
|
}
|
|
void resetstep()
|
{
|
}
|
|
void setmaxcount(int i)
|
{
|
maxcount = i;
|
}
|
|
void settransformcount(int i)
|
{
|
transformcount = i;
|
}
|
|
void setstep(int i)
|
{
|
step = i;
|
}
|
|
// int acceleration;
|
|
int delay;
|
int countdown;
|
|
transient int currentframe; // do only one step per frame
|
|
int GetTransformCount()
|
{
|
// patch pour serialization de Texture
|
resetmaxcount();
|
resettransformcount();
|
resetstep();
|
|
if (this instanceof Mocap || this instanceof cMesh)
|
{
|
return 1;
|
}
|
|
if (step == 0)
|
step = 1;
|
if (maxcount == 0)
|
maxcount = 128; // 2048; // 4;
|
// if (acceleration == 0)
|
// acceleration = 10;
|
if (delay == 0) // serial
|
{
|
countdown = delay = 5;
|
}
|
|
int factor = 1;
|
|
// if (!CameraPane.AntialiasingEnabled())
|
// {
|
// factor = 4; // patch for 2x2 antialiasing only
|
// }
|
|
// if (CameraPane.FAST)
|
// {
|
// // aout 2013
|
// factor = CameraPane.STEP;
|
// }
|
|
if (marked && Globals.isLIVE() && live &&
|
//TEMP21aug2018
|
(Globals.DrawMode() == iCameraPane.SHADOW || !Globals.RENDERSHADOW || !Globals.COMPUTESHADOWWHENLIVE) &&
|
currentframe != Globals.framecount)
|
{
|
currentframe = Globals.framecount;
|
|
// System.err.println("transformcount = " + transformcount);
|
// System.err.println("factor = " + factor);
|
// System.err.println("maxcount = " + maxcount);
|
// System.err.println("step = " + step);
|
|
boolean changedir = random && Math.random() < 0.01; // && !link2master;
|
|
if (transformcount*factor >= maxcount && (rewind || random) ||
|
(step == 1 && changedir))
|
{
|
countdown = 1;
|
delay = speedup?8:1;
|
//delay = 0; // 10;
|
if (rewind) // link2master patch for loop
|
transformcount = 0;
|
else
|
step = -1;
|
|
changedir = false;
|
}
|
if (transformcount <= 0 || (step == -1 && changedir))
|
{
|
countdown = 1;
|
delay = speedup?8:1;
|
//delay = 0; // 10;
|
step = 1;
|
}
|
|
if (--countdown == 00) // || link2master) // patch for loop
|
{
|
if (CameraPane.FAST)
|
transformcount += step * CameraPane.STEP;
|
else
|
transformcount += step;
|
delay--;
|
if (delay == 0)
|
delay = 1;
|
countdown = delay;
|
}
|
|
// if (maxcount <= 1000)
|
// {
|
// //if (step < acceleration)
|
// if (transformcount < acceleration*(acceleration+1)/2)
|
// step += 1;
|
//
|
// if (transformcount > maxcount - acceleration*(acceleration+1)/2)
|
// step -= 1;
|
// }
|
}
|
|
if (marked) // live)
|
{
|
// if (transformcount < 10)
|
// return transformcount*transformcount;
|
// else
|
// if (transformcount > maxcount-10)
|
// return transformcount*transformcount;
|
// else
|
// if (transformcount > 1)
|
// System.out.println("Transform count (" + this + ") = " + transformcount);
|
return transformcount * factor;
|
}
|
else
|
{
|
if (maxcount == 4) // grosse patch
|
return 1;
|
else
|
return 1; // may 2013 maxcount;
|
}
|
}
|
|
|
boolean IsStatic()
|
{
|
// return true;
|
|
// if (material == null || material.multiply)
|
// return true;
|
//
|
// if (projectedVertices != null && projectedVertices.length > 2 && projectedVertices[2].y >= 10000)
|
// return false;
|
//
|
// // Transparent objects are dynamic because we have to sort the triangles.
|
// return material.opacity > 0.99;
|
|
return !sort;
|
}
|
|
boolean IsOpaque()
|
{
|
// return true;
|
|
// if (material == null || material.multiply)
|
// return true;
|
//
|
// return material.opacity > 0.99;
|
|
return !sort;
|
}
|
|
Object3D()
|
{
|
this("Default Object");
|
|
toParent = LA.newMatrix();
|
fromParent = LA.newMatrix();
|
}
|
|
Object3D(String oname)
|
{
|
super(0, 0); // Vector
|
centerPt = null; // new Point(0, 0);
|
startMat = null; // new double[4][4];
|
name = oname;
|
toParent = null; // LA.newMatrix();
|
fromParent = null; // LA.newMatrix();
|
bRep = null; // new BoundaryRep();
|
|
if (oname != null && oname.equals("LeftHand"))
|
{
|
name = oname;
|
}
|
|
/*
|
float hue = (float)Math.random();
|
Color col;
|
col = Color.getHSBColor(hue, 0.5f, 1f);
|
aColor = new Color(col.getRed(), col.getGreen(), col.getBlue(), 192);
|
col = Color.getHSBColor(hue, 0.5f, 1f);
|
aColorSelect = new Color(col.getRed(), col.getGreen(), col.getBlue());
|
col = Color.getHSBColor(hue, 0.5f, 0.2f);
|
aLineColor = new Color(col.getRed(), col.getGreen(), col.getBlue());
|
col = Color.getHSBColor(hue, 0.5f, 1);
|
aLineColorSelect = new Color(col.getRed(), col.getGreen(), col.getBlue());
|
*/
|
|
//InitColorTable();
|
viewCode = -1; // cache for transparency
|
}
|
|
Color tmpFillColor = null; // new Color(0,0,0);
|
/*
|
//transient Color[] colorTable = new Color[100];
|
void InitColorTable()
|
{
|
int len = colorTable.length;
|
for (int i=0; i<len; i++)
|
{
|
colorTable[i] = new Color(aColor.getRed() * i / len,
|
aColor.getGreen() * i / len,
|
aColor.getBlue() * i / len, 128);
|
}
|
}
|
*/
|
|
Object3D deepCopy()
|
{
|
// ??? display list failure!! ---->>> return (Object3D) Applet3D.clone(this);
|
Object3D obj = new Object3D();
|
deepCopySelf(obj);
|
return obj;
|
}
|
|
public Object clone()
|
{
|
return Grafreed.clone(this);
|
}
|
|
Object3D copyExpand()
|
{
|
// parent problem...
|
// return this;
|
|
// will share the geometry
|
assert (!(this instanceof Composite));
|
|
Object3D obj = deepCopy(); // Never called for Composite
|
obj.count = 2;
|
return obj;
|
}
|
|
boolean HasLoops()
|
{
|
return false;
|
}
|
|
void ResetUUIDs()
|
{
|
if (blockloop)
|
{
|
return;
|
}
|
|
this.uuid = null;
|
|
blockloop = true;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D obj = (Object3D) Children().get(i);
|
|
if (obj != null)
|
{
|
obj.ResetUUIDs();
|
}
|
}
|
|
blockloop = false;
|
}
|
|
boolean IsInfinite()
|
{
|
if (blockloop)
|
{
|
return true;
|
}
|
|
blockloop = true;
|
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D obj = (Object3D) Children().get(i);
|
|
if (obj == null)
|
{
|
//new Exception().printStackTrace();
|
//return true;
|
continue;
|
}
|
if (obj.IsInfinite())
|
{
|
blockloop = false;
|
return true;
|
}
|
}
|
|
blockloop = false;
|
return false;
|
}
|
|
void CopyExtraMaterial(Object3D other)
|
{
|
if (projectedVertices != null && projectedVertices.length > 0)
|
{
|
other.projectedVertices = new cVector2[3];
|
other.projectedVertices[0] = new cVector2();
|
other.projectedVertices[1] = new cVector2();
|
other.projectedVertices[2] = new cVector2();
|
other.projectedVertices[2].y = 1;
|
if (projectedVertices[0] != null) // ??
|
{
|
other.projectedVertices[0].x = projectedVertices[0].x; // bump
|
other.projectedVertices[0].y = projectedVertices[0].y; // noise
|
}
|
if (projectedVertices.length > 1)
|
{
|
if (projectedVertices[1] != null) // ??
|
{
|
other.projectedVertices[1].x = projectedVertices[1].x; // borderfade
|
other.projectedVertices[1].y = projectedVertices[1].y; // fog
|
}
|
if (projectedVertices.length > 2)
|
{
|
if (projectedVertices[2] != null) // ??
|
{
|
other.projectedVertices[2].x = projectedVertices[2].x; // noise power
|
other.projectedVertices[2].y = projectedVertices[2].y; // opacity power
|
}
|
}
|
}
|
}
|
}
|
|
// copy this into other
|
void deepCopySelf(Object3D other)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
other.parent = parent;
|
|
//System.out.println("COPY " + this + " to " + other);
|
//new Exception().printStackTrace();
|
deepCopyNode(other);
|
|
other.bRep = bRep; // Share the geometry
|
|
other.support = support; // Share the support
|
|
// aout 2013 if (/*displaylist != -1 &&*/other.displaylist != displaylist)
|
// {
|
// CameraPane.RemoveList(other.displaylist);
|
// other.displaylist = displaylist; // Share
|
// }
|
//
|
// CameraPane.AddDuplicate(displaylist);
|
|
Object3D c = (Object3D) other;
|
// if (selection != null)
|
// {
|
//// assert(false); // ?!?!?!?!?!
|
// c.selection = /*(Vector)*/ (Object3D) selection.clone();
|
// } else
|
// {
|
// c.selection = new Object3D(); // Vector(0, 0);
|
// }
|
assert (c.Children() == c);
|
//?? c.clear();
|
/**/
|
c.Children().setSize(Children().Size());
|
for (int i=0; i < Children().Size(); i++)
|
{
|
Object3D obj = (Object3D)Children().get(i);
|
if (IsContainedIn(obj))
|
{
|
// assert(false); // ?!?!?!?!?!
|
c.Children().setElementAt(c, i);
|
}
|
else
|
{
|
obj = obj.deepCopy();
|
obj.parent = c;
|
c.Children().setElementAt(obj, i);
|
}
|
}
|
/**/
|
|
//other.displaylist = -1;
|
//other.Touch();
|
blockloop = false;
|
}
|
|
void overwriteNode(Object3D other, int mask)
|
{
|
// System.err.println("overwrite " + other + " to " + this);
|
//new Exception().printStackTrace();
|
|
// LA.matCopy(other.toParent, toParent);
|
// LA.matCopy(other.fromParent, fromParent);
|
|
if ((mask & GEOMETRY) != 0)
|
{
|
if (bRep != null)
|
{
|
bRep.overwriteThis(other.bRep==null?other.transientrep:other.bRep);
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0; // june 2013 -1;
|
}
|
else
|
{
|
//assert(other.bRep == null);
|
bRep = other.bRep;
|
}
|
|
// if (bRep != null)
|
// {
|
// CameraPane.RemoveList(bRep.displaylist);
|
// bRep.displaylist = 0; // june 2013 -1;
|
// }
|
// else
|
// bRep = bRep;
|
}
|
|
/* Use a MASK = GEO/MAT
|
*/
|
if ((mask & NAME) != 0)
|
{
|
if (bRep == null || other.bRep == null || bRep.VertexCount() != other.bRep.VertexCount()) // don't rename leaves. june 2014
|
{
|
if (other.name != null)
|
name = new String(other.name);
|
}
|
//else name = null;
|
else if (bRep != null && other.bRep != null)
|
{
|
System.out.println("" + name + " to " + other.name + ": not renamed (same mesh).");
|
}
|
}
|
|
if ((mask & UV) != 0)
|
{
|
if (bRep != null)
|
{
|
BoundaryRep otherrep = other.bRep==null?other.transientrep:other.bRep;
|
|
if (bRep.VertexCount() == otherrep.VertexCount())
|
{
|
for (int i=0; i<bRep.VertexCount(); i++)
|
{
|
Vertex v2 = bRep.GetVertex(i);
|
Vertex v = null; // otherrep.GetVertex(i);
|
|
double dist2 = Double.MAX_VALUE;
|
int mini = 0;
|
|
// closest vertex
|
for (int j=0; j<otherrep.VertexCount(); j++)
|
{
|
v = otherrep.GetVertex(j);
|
|
v0.set(v2);
|
v0.sub(v);
|
|
if (dist2 > v0.dot(v0))
|
{
|
dist2 = v0.dot(v0);
|
mini = j;
|
}
|
}
|
|
v = otherrep.GetVertex(mini);
|
|
v2.s = v.s;
|
v2.t = v.t;
|
|
bRep.SetVertex(v2, i); // if trimmed
|
}
|
}
|
}
|
else
|
assert(other.bRep == null);
|
|
if (bRep != null)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0; // june 2013 -1;
|
}
|
else
|
bRep = bRep;
|
}
|
|
// if ((mask & MATERIAL) != 0)
|
// {
|
// if (other.material != null)
|
// {
|
// material = new cMaterial(other.material);
|
// } else
|
// {
|
// //assert(other.material == null);
|
// //material = null; // ?
|
// }
|
// }
|
//
|
// if ((mask & TEXTURE) != 0)
|
// GetTextures().name = other.GetTextures().name;
|
SetAttributes(other, mask);
|
|
if ((mask & TRANSFORM) != 0)
|
{
|
if (other.toParent != null)
|
{
|
if (toParent == null)
|
{
|
toParent = LA.newMatrix();
|
fromParent = LA.newMatrix();
|
}
|
|
LA.matCopy(other.toParent, toParent);
|
LA.matCopy(other.fromParent, fromParent);
|
|
if (other.toParentMarked != null)
|
{
|
toParentMarked = LA.newMatrix();
|
fromParentMarked = LA.newMatrix();
|
LA.matCopy(other.toParentMarked, toParentMarked);
|
LA.matCopy(other.fromParentMarked, fromParentMarked);
|
}
|
|
//live = other.live;
|
marked = other.marked;
|
maxcount = other.maxcount;
|
transformcount = other.transformcount;
|
step = other.step;
|
delay = other.delay;
|
countdown = other.countdown;
|
if (material == null)
|
material = other.material; // for selection
|
}
|
else
|
{
|
//assert(toParent == null);
|
// if (toParent != null)
|
toParent = null;
|
fromParent = null;
|
}
|
}
|
|
/*
|
if (projectedVertices != null && projectedVertices.length > 0)
|
{
|
other.projectedVertices = new cVector2[3];
|
other.projectedVertices[0] = new cVector2();
|
other.projectedVertices[1] = new cVector2();
|
other.projectedVertices[2] = new cVector2();
|
other.projectedVertices[2].y = 1;
|
if (projectedVertices[0] != null) // ??
|
{
|
other.projectedVertices[0].x = projectedVertices[0].x; // bump
|
other.projectedVertices[0].y = projectedVertices[0].y; // noise
|
}
|
if (projectedVertices.length > 1)
|
{
|
if (projectedVertices[1] != null) // ??
|
{
|
other.projectedVertices[1].x = projectedVertices[1].x; // borderfade
|
other.projectedVertices[1].y = projectedVertices[1].y; // fog
|
}
|
if (projectedVertices.length > 2)
|
{
|
if (projectedVertices[2] != null) // ??
|
{
|
other.projectedVertices[2].x = projectedVertices[2].x; // noise power
|
other.projectedVertices[2].y = projectedVertices[2].y; // opacity power
|
}
|
}
|
}
|
}
|
*/
|
|
touched = true;
|
softtouched = true;
|
}
|
|
void morphNode(Object3D other, int index, double[] morphweights)
|
{
|
//assert(other == morphobject);
|
|
// double totalweight = 0;
|
//
|
// for (int i=0; i<morphweights.length; i++)
|
// {
|
// totalweight += morphweights[i];
|
// }
|
|
if (bRep != null)
|
{
|
Object3D firstobject = other.get(0);
|
|
if (index != -1)
|
firstobject = firstobject.get(index);
|
|
BoundaryRep firstrep = firstobject.bRep==null ? firstobject.transientrep : firstobject.bRep;
|
|
double totalweight = 0;
|
|
for (int m=morphweights.length; --m>=0;)
|
{
|
totalweight += morphweights[m];
|
}
|
|
//if (bRep.VertexCount() == otherrep.VertexCount())
|
{
|
for (int i=bRep.VertexCount(); --i>=0;)
|
{
|
Vertex v2 = firstrep.GetVertex(i);
|
//Vertex v = null; // otherrep.GetVertex(i);
|
|
double x = v2.x;
|
double y = v2.y;
|
double z = v2.z;
|
|
double nx = v2.norm.x;
|
double ny = v2.norm.y;
|
double nz = v2.norm.z;
|
|
for (int m=morphweights.length; --m>=0;)
|
{
|
Object3D otherobject = other.get(m);
|
|
if (index != -1)
|
otherobject = otherobject.get(index);
|
|
BoundaryRep otherrep = otherobject.bRep==null ? otherobject.transientrep : otherobject.bRep;
|
|
// if (bRep.VertexCount() != otherrep.VertexCount())
|
// {
|
// new Exception().printStackTrace();
|
// continue;
|
// }
|
|
Vertex v = otherrep.GetVertex(i);
|
|
double weight = morphweights[m];
|
|
if (weight == 0)
|
continue;
|
|
// x += weight * (v.x - v2.x);
|
// y += weight * (v.y - v2.y);
|
// z += weight * (v.z - v2.z);
|
// nx += weight * (v.norm.x - v2.norm.x);
|
// ny += weight * (v.norm.y - v2.norm.y);
|
// nz += weight * (v.norm.z - v2.norm.z);
|
x += weight * v.x;
|
y += weight * v.y;
|
z += weight * v.z;
|
|
nx += weight * v.norm.x;
|
ny += weight * v.norm.y;
|
nz += weight * v.norm.z;
|
}
|
|
x -= totalweight * v2.x;
|
y -= totalweight * v2.y;
|
z -= totalweight * v2.z;
|
|
nx -= totalweight * v2.norm.x;
|
ny -= totalweight * v2.norm.y;
|
nz -= totalweight * v2.norm.z;
|
|
Vertex v3 = bRep.GetVertex(i);
|
|
v3.x = x;
|
v3.y = y;
|
v3.z = z;
|
|
double length = Math.sqrt(nx*nx + ny*ny + nz*nz);
|
|
v3.norm.x = nx / length;
|
v3.norm.y = ny / length;
|
v3.norm.z = nz / length;
|
|
bRep.SetVertex(v3, i); // if trimmed
|
}
|
}
|
}
|
else
|
assert(other.bRep == null);
|
|
if (bRep != null)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0; // june 2013 -1;
|
}
|
else
|
bRep = bRep;
|
|
touched = true;
|
softtouched = true;
|
}
|
|
void linkVerticesNode(Object3D other)
|
{
|
// if (other == null)
|
// return;
|
|
if (other != null)
|
{
|
BoundaryRep.SEUIL = other.material.cameralight;
|
|
// Set default to 0.1
|
BoundaryRep.SEUIL /= 4; // 2;
|
System.out.println("SEUIL = " + BoundaryRep.SEUIL);
|
}
|
|
System.out.println("Link this = " + this + "; support = " + other);
|
|
//if (bRep != null)
|
// bRep.linkVerticesThis(other.bRep);
|
if (bRep != null)
|
{
|
//assert(other.bRep != null);
|
BoundaryRep usedrep = null;
|
|
if (other != null)
|
{
|
usedrep = other.bRep;
|
|
if (usedrep == null)
|
usedrep = other.transientrep;
|
}
|
|
//assert(usedrep != null);
|
if (usedrep == null && other != null)
|
{
|
new Exception().printStackTrace();
|
}
|
else
|
bRep.linkVerticesThis(usedrep, other==null?null:null); // june 2013 other.GlobalTransformInv());
|
}
|
else
|
{
|
if (transientrep != null)
|
{
|
BoundaryRep usedrep = null;
|
|
if (other != null)
|
{
|
usedrep = other.bRep;
|
|
if (usedrep == null)
|
usedrep = other.transientrep;
|
}
|
|
if (usedrep != null || other != null)
|
transientrep.linkVerticesThis(usedrep, other==null?null:null); // june 2013 other.GlobalTransformInv());
|
else
|
//assert(usedrep != null);
|
new Exception().printStackTrace();
|
}
|
}
|
// else
|
// assert(other.bRep == null);
|
|
|
// System.out.println("Done.");
|
|
// touched = true;
|
// softtouched = true;
|
// CameraPane.RemoveList(displaylist);
|
// displaylist = -1;
|
}
|
|
void setMasterNode(Object3D other, boolean smooth)
|
{
|
//other.getBounds(min,max,true);
|
//System.out.println("Link object " + this + " to " + other);
|
if (name != null && name.contains("pantsstraps"))
|
{
|
name = name;
|
}
|
|
if (bRep != null)
|
{
|
//assert(other.bRep != null);
|
BoundaryRep usedrep = other.bRep;
|
|
if (usedrep == null)
|
usedrep = other.transientrep;
|
|
//assert(usedrep != null);
|
if (usedrep == null)
|
{
|
System.err.println(this);
|
System.err.println("other = " + other);
|
new Exception().printStackTrace();
|
}
|
else
|
bRep.setMasterThis(usedrep, null /* june 2013 other.GlobalTransformInv()*/, smooth, marked);
|
}
|
else
|
{
|
BoundaryRep usedrep = other.bRep;
|
|
if (usedrep == null)
|
{
|
if (other.transientrep == null)
|
other.Revert();
|
|
usedrep = other.transientrep;
|
}
|
|
//assert(usedrep != null);
|
if (usedrep == null)
|
{
|
new Exception().printStackTrace();
|
return;
|
}
|
|
if (transientrep == null)
|
Revert();
|
|
if (transientrep != null)
|
{
|
transientrep.setMasterThis(usedrep, null /* june 2013 other.GlobalTransformInv()*/, smooth, marked);
|
}
|
}
|
|
Touch();
|
// touched = true;
|
// softtouched = true;
|
// CameraPane.RemoveList(displaylist);
|
// displaylist = -1;
|
}
|
|
void resetMasterNode(boolean smooth)
|
{
|
//System.err.println("Reset support this = " + this + "; support = " + support);
|
if (support != null)
|
setMasterNode(support, smooth);
|
//support.
|
//getBounds(min,max,true);
|
}
|
|
void overwriteThis(Object3D other, int mask)
|
{
|
if (blockloop)
|
return;
|
|
if ((mask & NAME) != 0)
|
mask = mask;
|
|
overwriteNode(other, mask);
|
|
// assert(Size() == other.Size());
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
Object3D obj2 = null;
|
|
if ((mask & NAME) == 0 && obj.name != null)
|
{
|
obj2 = other.get(obj.name);
|
|
// june 2014
|
if (obj2 == null && other.bRep == null)
|
{
|
// Not found. We cannot continue with an empty geometry.
|
if (other.Size() == Size())
|
{
|
// we try at the same index
|
obj2 = other.get(i);
|
}
|
else
|
{
|
new Exception("Geometry mismatch: " + obj + " of " + this).printStackTrace();
|
}
|
}
|
}
|
else
|
{
|
if (i < other.Size())
|
obj2 = other.get(i); // no choice
|
}
|
|
if (obj2 != null)
|
{
|
blockloop = true;
|
obj.overwriteThis(obj2, mask); //i));
|
blockloop = false;
|
}
|
}
|
}
|
|
void morphThis(Object3D other, int index, double[] morphweights)
|
{
|
if (blockloop)
|
return;
|
|
morphNode(other, index, morphweights);
|
|
// assert(Size() == other.Size());
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
Object3D obj2 = null;
|
|
if (obj.name != null)
|
{
|
obj2 = other.get(obj.name);
|
}
|
else
|
{
|
if (i < other.Size())
|
obj2 = other.get(i); // no choice
|
}
|
|
if (obj2 != null)
|
{
|
blockloop = true;
|
obj.morphThis(obj2, i, morphweights);
|
blockloop = false;
|
}
|
}
|
}
|
|
void generateMeshes() // Object3D group)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
cMesh s = new cMesh(this);
|
s.setup();
|
DecCount();
|
parent.addChild(s);
|
}
|
|
int size = Size();
|
for (int i=0; i<size; i++)
|
//for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
obj.generateMeshes();
|
}
|
|
blockloop = false;
|
}
|
|
void ExtractGeometries(Object3D group, boolean clone)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (transientrep != null)
|
{
|
assert(bRep == null);
|
Object3D o = new Object3D((clone?"Ge:":"Li:") + this.name);
|
o.bRep = transientrep;
|
if (clone)
|
o.bRep = (BoundaryRep) Grafreed.clone(transientrep);
|
o.CreateMaterial();
|
o.SetAttributes(this, -1);
|
//parent
|
group.addChild(o);
|
}
|
|
if (bRep != null)
|
{
|
assert(transientrep == null);
|
Object3D o = new Object3D((clone?"Ge:":"Li:") + this.name);
|
o.bRep = bRep;
|
if (clone)
|
o.bRep = (BoundaryRep) Grafreed.clone(bRep);
|
o.CreateMaterial();
|
//o.overwriteThis(this, -1);
|
o.SetAttributes(this, -1);
|
//parent
|
group.addChild(o);
|
}
|
|
int size = Size();
|
for (int i=0; i<size; i++)
|
//for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
if (obj.bRep == null)
|
{
|
Object3D newgroup = new Object3D((clone?"Ge:":"Li:") + obj.name);
|
|
obj.ExtractGeometries(newgroup, clone);
|
|
group.addChild(newgroup);
|
}
|
else
|
{
|
obj.ExtractGeometries(group, clone);
|
}
|
}
|
|
blockloop = false;
|
}
|
|
// void CloneGeometries()
|
// {
|
// if (blockloop)
|
// return;
|
//
|
// blockloop = true;
|
//
|
// if (transientrep != null)
|
// {
|
// assert(bRep == null);
|
// Object3D o = new Object3D("Geometry:" + this.name);
|
// o.bRep = (BoundaryRep) GrafreeD.clone(transientrep);
|
// o.CreateMaterial();
|
// parent.addChild(o);
|
// }
|
//
|
// if (bRep != null)
|
// {
|
// assert(transientrep == null);
|
// Object3D o = new Object3D("Geometry:" + this.name);
|
// o.bRep = (BoundaryRep) GrafreeD.clone(bRep);
|
// o.CreateMaterial();
|
// parent.addChild(o);
|
// }
|
//
|
// int size = Size();
|
// for (int i=0; i<size; i++)
|
// //for (int i=Size(); --i>=0;)
|
// {
|
// Object3D obj = get(i);
|
//
|
// obj.CloneGeometries();
|
// }
|
//
|
// blockloop = false;
|
// }
|
|
//@SuppressWarnings("CallToThreadDumpStack")
|
Object3D get(String n)
|
{
|
if (blockloop)
|
return null;
|
|
blockloop = true;
|
|
int count = 0;
|
|
Object3D theobj = null;
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
if (obj.name == null)
|
continue; // can't be a null one
|
|
// Try perfect match first.
|
if (n.equals(obj.name))
|
{
|
theobj = obj;
|
count++;
|
}
|
}
|
|
// not needed: n = n.split(":")[0]; // Poser generates a count
|
|
if (count != 1)
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
if (obj.name == null)
|
continue; // can't be a null one
|
|
String name = obj.name.split(":")[0]; // Poser generates a count
|
//if (n.startsWith(obj.name))
|
if (n.contains(name))
|
{
|
theobj = obj;
|
count++;
|
}
|
}
|
|
blockloop = false;
|
|
if (count != 1)
|
{
|
if (count > 1)
|
new Exception().printStackTrace();
|
return null;
|
}
|
else
|
return theobj;
|
}
|
|
void linkVerticesThis(Object3D other)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null) // && !bRep.trimmed)
|
{
|
support = other;
|
|
link2master = support != null;
|
|
if (support != null && bRep.trimmed)
|
{
|
System.out.println("Untrim " + this);
|
bRep.Untrim();
|
}
|
|
linkVerticesNode(other);
|
}
|
|
//if (bRep != null)
|
// bRep.linkVerticesThis(other, other.GlobalTransformInv());
|
|
// assert(Size() == other.Size());
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
|
if (other == null)
|
{
|
obj.linkVerticesThis(null);
|
}
|
else
|
{
|
Object3D obj2 = other.get(obj.name);
|
|
if (obj2 != null)
|
obj.linkVerticesThis(obj2);
|
else
|
{
|
obj2 = other;
|
if (other.bRep == null)
|
{
|
// Not found. We cannot continue with an empty geometry.
|
if (other.Size() == Size())
|
{
|
// we try at the same index
|
obj2 = other.get(i);
|
}
|
else
|
{
|
new Exception("Support mismatch").printStackTrace();
|
}
|
}
|
obj.linkVerticesThis(obj2);
|
}
|
}
|
}
|
|
blockloop = false;
|
}
|
|
void ClearReferences()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
|
obj.ClearReferences();
|
}
|
|
blockloop = false;
|
}
|
|
void setMasterThis(Object3D other, boolean smooth)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
setMasterNode(other, smooth);
|
|
// assert(Size() == other.Size());
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
|
Object3D obj2 = other.get(obj.name);
|
|
if (obj2 != null)
|
obj.setMasterThis(obj2, smooth);
|
else
|
obj.setMasterThis(other, smooth);
|
}
|
|
blockloop = false;
|
}
|
|
void RelinkToSupport()
|
{
|
if (blockloop)
|
return;
|
|
// setMasterNode(other, smooth);
|
|
if (bRep != null)
|
{
|
// assert(bRep.support == support.bRep);
|
|
Object3D sup = support;
|
|
support = null;
|
bRep.support = null;
|
|
linkVerticesThis(null);
|
linkVerticesThis(sup);
|
}
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
|
blockloop = true;
|
obj.RelinkToSupport();
|
blockloop = false;
|
}
|
|
}
|
|
void resetMaster(boolean smooth)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
resetMasterNode(smooth);
|
|
// assert(Size() == other.Size());
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
obj.resetMaster(smooth);
|
}
|
|
blockloop = false;
|
}
|
|
void poseMeshThis(Object3D other)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (this instanceof cMesh)
|
{
|
if (other != null)
|
{
|
// assert(other instanceof cMesh);
|
}
|
|
cMesh meshthis = (cMesh) this;
|
|
/*
|
if (meshthis.Phys == null)
|
meshthis.InitPhysics();
|
|
meshthis.Phys.SetPose(other);
|
*/
|
meshthis.pose = other;
|
}
|
|
// if (other != null)
|
// assert(Size() == other.Size());
|
|
for (int i=0; i < Size(); i++)
|
{
|
Object3D obj = get(i);
|
|
if (other != null)
|
{
|
Object3D obj2 = other.get(obj.name);
|
|
if (obj2 == null) // ?
|
obj2 = other.get(i);
|
|
obj.poseMeshThis(obj2);
|
}
|
else
|
obj.poseMeshThis(null);
|
}
|
|
blockloop = false;
|
}
|
|
void ResetTransparency()
|
{
|
//System.out.println("ResetTransparency " + this); //new Exception().printStackTrace();
|
viewCode = -1;
|
if (parent != null)
|
{
|
parent.ResetTransparency();
|
}
|
}
|
|
void ClearMaterial()
|
{
|
// nov 2012 if (parent != null)
|
{
|
material = null;
|
// if (projectedVertices.length > 0)
|
// {
|
// projectedVertices[0] = null;
|
// } // Others
|
SoftTouch();
|
ResetTransparency();
|
}
|
}
|
|
void ClearMaterialS()
|
{
|
if (selection.size() == 0)
|
{
|
//super.ClearMaterial();
|
} else
|
{
|
for (int i = 0; i < selection.size(); i++)
|
{
|
Object3D o = (Object3D) selection.get(i);
|
if (o == this)
|
{
|
//super.
|
ClearMaterial();
|
continue;
|
}
|
o.ClearMaterial();
|
}
|
}
|
}
|
|
void CreateMaterial()
|
{
|
CreateMaterial(false);
|
}
|
|
void CreateMaterialS(boolean multiply)
|
{
|
if (selection.size() == 0)
|
{
|
//super.CreateMaterial(multiply);
|
} else
|
{
|
for (int i = 0; i < selection.size(); i++)
|
{
|
Object3D o = (Object3D) selection.get(i);
|
if (o != this)
|
{
|
o.CreateMaterial(multiply);
|
} else
|
{
|
//super.
|
CreateMaterial(multiply);
|
}
|
}
|
}
|
}
|
|
void CreateMaterial(boolean multiply)
|
{
|
if (/*parent != null &&*/ material == null)
|
{
|
material = new cMaterial(GetMaterial());
|
|
InitOthers();
|
|
material.multiply = multiply;
|
|
if (multiply)
|
{
|
material.color =
|
material.modulation =
|
material.metalness =
|
material.diffuse =
|
material.specular =
|
material.shininess =
|
material.shift =
|
material.ambient =
|
material.lightarea =
|
material.factor =
|
material.velvet =
|
material.sheen =
|
material.subsurface =
|
material.bump =
|
material.aniso =
|
material.anisoV =
|
material.cameralight =
|
material.diffuseness =
|
material.shadow =
|
material.texture =
|
material.opacity =
|
material.fakedepth =
|
material.shadowbias = 0.5f;
|
}
|
|
SoftTouch();
|
ResetTransparency();
|
}
|
}
|
|
void setParent(Object3D /*Composite*/ parent)
|
{
|
this.parent = parent;
|
}
|
|
|
transient // mar 2014
|
boolean blockloop = false;
|
transient // june 2014
|
boolean blockdraw = false;
|
|
boolean IsContainedIn(Object o)
|
{
|
if (this == o)
|
{
|
return true;
|
}
|
|
if (parent == null)
|
{
|
return false;
|
}
|
|
if (blockloop)
|
{
|
blockloop = false;
|
return false;
|
}
|
|
boolean b = false;
|
try
|
{
|
/*parent.*/ blockloop = true;
|
b = parent.IsContainedIn(o);
|
/*parent.*/ blockloop = false;
|
} catch (Error e)
|
{
|
System.out.println(e);
|
}
|
|
return b;
|
}
|
|
void UpdateMaterial(cMaterial anchor, cMaterial current, boolean propagate)
|
{
|
if (blockloop)
|
{
|
return;
|
}
|
|
// super.UpdateMaterial(anchor, current, false);
|
if (material != null)
|
{
|
material.UpdateMaterial(anchor, current);
|
}
|
|
if (!propagate)
|
{
|
return;
|
}
|
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D child = (Object3D) Children().reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.UpdateMaterial(anchor, current, propagate);
|
blockloop = false;
|
Children().release(i);
|
}
|
|
int temp = count;
|
|
count = 0; // try leaf
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D child = (Object3D) Children().reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.UpdateMaterial(anchor, current, propagate);
|
blockloop = false;
|
Children().release(i);
|
}
|
|
count = temp;
|
}
|
|
void openEditWindow(GroupEditor callee, boolean newWindow) // , boolean root)
|
{
|
// NEW sept2012
|
if (editWindow == null || (newWindow && editWindow != callee.GetEditor()))
|
{
|
createEditWindow(callee, newWindow); //, root);
|
/*
|
if(editWindow != null)
|
{
|
editWindow.setTitle(name);
|
editWindow.show();
|
}
|
*/
|
}
|
else
|
{
|
//((ObjEditor)editWindow).SetupUI2(null);
|
if (objectUI != null)
|
((ObjEditor)objectUI).pinButton.setSelected(pinned);
|
else
|
//new Exception().printStackTrace();
|
System.err.println("objectUI is null");
|
}
|
}
|
|
void createEditWindow(GroupEditor callee, boolean newWindow) //, boolean root)
|
{
|
if (newWindow)
|
{
|
new Exception().printStackTrace();
|
System.exit(0);
|
if (parent != null)
|
{
|
editWindow = new ObjEditor(this, deepCopy(), callee);
|
} else
|
{
|
editWindow = new ObjEditor(this, this, callee);
|
}
|
|
editWindow.SetupWindow(); // PATCH!!
|
} else
|
{
|
objectUI = new ObjEditor(this, callee);
|
editWindow = objectUI.GetEditor();
|
((ObjEditor) objectUI).SetupUI2(callee);
|
}
|
}
|
|
void closeEditWindow()
|
{
|
if (editWindow != null)
|
{
|
editWindow.Clear();
|
editWindow.frame.dispose();
|
}
|
editWindow = null;
|
}
|
|
void refreshEditWindow()
|
{
|
if (editWindow != null)
|
{
|
editWindow.refreshContents();
|
}
|
else
|
{
|
if (manipWindow != null)
|
{
|
manipWindow.refreshContents();
|
}
|
}
|
|
//if (parent != null)
|
//parent.refreshEditWindow();
|
}
|
|
// public void applySelf()
|
// {
|
// if (editWindow != null)
|
// {
|
// editWindow.applySelf();
|
// }
|
//
|
// refreshEditWindow();
|
// }
|
|
// void ClearUI()
|
// {
|
// CloseUI();
|
// }
|
|
static int debugdepth; //
|
|
void ClearUI()
|
{
|
if (blockloop)
|
{
|
return;
|
}
|
|
//super.ClearUI();
|
CloseUI();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
if (debugdepth == 0)
|
i = - -i;
|
if (debugdepth == 1)
|
i = - -i;
|
if (debugdepth == 2)
|
i = - -i;
|
debugdepth++;
|
child.ClearUI();
|
debugdepth--;
|
blockloop = false;
|
//Children().release(i);
|
}
|
}
|
|
void addSelectee(Object3D child)
|
{
|
// We accept multiple link...
|
if (false) // selectees.indexOf(child) != -1)
|
{
|
//assert (selectees.indexOf(child) == -1);
|
System.out.println("Child = " + child + "; this = " + this);
|
new Exception().printStackTrace();
|
}
|
|
if (selection != null)
|
selection.addElement(child);
|
//? child.SoftTouch();
|
}
|
|
void removeSelectee(Object3D child)
|
{
|
selection.removeElement(child);
|
//? child.SoftTouch();
|
}
|
|
transient private Object3D childToDrag;
|
|
transient private int doSomething;
|
// transient private Object3D childToDrag;
|
private static final int doNothing = 0;
|
private static final int editSelf = 1;
|
private static final int editChild = 2;
|
|
void drawEditHandles(//ClickInfo info,
|
int level)
|
{
|
if (level == 0)
|
{
|
if (selection == null)
|
return;
|
|
Object3D selectee;
|
for (java.util.Enumeration e = selection.elements(); e.hasMoreElements(); selectee.drawEditHandles(//info,
|
level + 1))
|
{
|
selectee = (Object3D) e.nextElement();
|
}
|
|
} else
|
{
|
//super.
|
drawEditHandles0(//info,
|
level + 1);
|
}
|
}
|
|
boolean doEditClick(//ClickInfo info,
|
int level)
|
{
|
doSomething = 0;
|
if (level == 0)
|
{
|
return doParentClick(); //info);
|
}
|
if (//super.
|
doEditClick0(//info,
|
level))
|
{
|
doSomething = 1;
|
return true;
|
} else
|
{
|
return false;
|
}
|
}
|
|
boolean doParentClick() //ClickInfo info)
|
{
|
if (selection == null)
|
{
|
new Exception().printStackTrace();
|
return false;
|
}
|
|
boolean retval = false;
|
|
for (java.util.Enumeration e = selection.elements(); e.hasMoreElements();)
|
{
|
Object3D selectee = (Object3D) e.nextElement();
|
if (selectee.doEditClick(//info,
|
1))
|
{
|
childToDrag = selectee;
|
doSomething = 2;
|
//return true;
|
retval = true;
|
}
|
}
|
|
return retval;
|
}
|
|
void doEditDrag(//ClickInfo clickInfo,
|
boolean opposite)
|
{
|
switch (doSomething)
|
{
|
case 1: // '\001'
|
//super.
|
doEditDrag0(//clickInfo,
|
opposite);
|
break;
|
|
case 2: // '\002'
|
// Use childToDrag for specific selection
|
for (int i = 0; i < selection.size(); i++)
|
{
|
Object3D sel = selection.get(i);
|
//System.out.println(" sel = " + sel);
|
if (sel != this) // childToDrag != this)
|
{
|
//sel.hitSomething = childToDrag.hitSomething;
|
//childToDrag.doEditDrag(info);
|
sel.doEditDrag(//clickInfo,
|
opposite);
|
} else
|
{
|
//super.
|
doEditDrag0(//clickInfo,
|
opposite);
|
}
|
}
|
break;
|
}
|
}
|
|
Object3D Children()
|
{
|
return this;
|
}
|
|
boolean doSelection(ClickInfo info, Rectangle r, int level)
|
{
|
if (level == 0)
|
{
|
deselectAll();
|
}
|
|
new Exception().printStackTrace();
|
|
ClickInfo newInfo = new ClickInfo();
|
newInfo.flags = info.flags;
|
newInfo.bounds = info.bounds;
|
newInfo.camera = info.camera;
|
newInfo.g = info.g;
|
newInfo.toScreen = info.toScreen;
|
|
if (newInfo.toScreen == null)
|
{
|
newInfo.toScreen = info.camera.toScreen;
|
}
|
if (level > 0)
|
{
|
newInfo.toScreen = new double[4][4];
|
LA.matConcat(toParent, info.toScreen, newInfo.toScreen);
|
}
|
boolean temp = false;
|
Object3D child;
|
int nb = Children().size();
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) Children().reserve(i);
|
boolean doSelect = child.doSelection(newInfo, r, level + 1);
|
Children().release(i);
|
|
if (doSelect)
|
{
|
temp = true;
|
if (level == 0)
|
{
|
addSelectee(child);
|
}
|
}
|
}
|
|
if (level == 0 && editWindow != null)
|
{
|
editWindow.refreshContents();
|
}
|
return temp;
|
}
|
|
void deselectAll()
|
{
|
childToDrag = null;
|
|
if (selection == null)
|
selection = new Object3D(); // new Exception().printStackTrace();
|
else
|
selection.clear();
|
//? SoftTouch();
|
}
|
|
void ClearSelection(boolean all)
|
{
|
if (all || (selection.size() > 0 && selection.get(0) == this))
|
{
|
selection.clear();
|
for (Object3D child : this)
|
{
|
child.ClearUI();
|
}
|
this.clear();
|
} else
|
{
|
Object3D selectee;
|
for (; selection.size() > 0; selectee.ClearUI(), removeChild(selectee))
|
{
|
selectee = (Object3D) selection.elementAt(0);
|
}
|
}
|
|
childToDrag = null;
|
|
Touch();
|
}
|
|
void GenUVS()
|
{
|
selection.GenUVs();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.GenUVs();
|
// }
|
|
//Touch();
|
}
|
|
void GenNormalsS(boolean crease)
|
{
|
selection.GenNormals(crease);
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.GenNormals(crease);
|
// }
|
|
//Touch();
|
}
|
|
void GenNormalsMeshS()
|
{
|
selection.GenNormalsMesh();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.GenNormals(crease);
|
// }
|
|
//Touch();
|
}
|
|
void ClearColorsS()
|
{
|
selection.ClearColors();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.ClearColors();
|
// }
|
|
//Touch();
|
}
|
|
void StripifyS()
|
{
|
selection.Stripify();
|
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.Stripify();
|
// }
|
|
//Touch();
|
}
|
|
void UnstripifyS()
|
{
|
selection.Unstripify();
|
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.Stripify();
|
// }
|
|
//Touch();
|
}
|
|
void TrimS()
|
{
|
selection.Trim();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.Trim();
|
// }
|
|
//Touch();
|
}
|
|
void UntrimS()
|
{
|
selection.Untrim();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.Untrim();
|
// }
|
|
//Touch();
|
}
|
|
void ReverseNormalsS()
|
{
|
selection.ReverseNormals();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.ReverseNormals();
|
// }
|
|
//Touch();
|
}
|
|
void ParseS(iParse obj)
|
{
|
selection.Parse(obj);
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.Parse(obj);
|
// }
|
|
//Touch();
|
}
|
|
void ReverseTrianglesS()
|
{
|
selection.ReverseTriangles();
|
// for (int i=0; i<selection.size(); i++)
|
// {
|
// Object3D selectee = (Object3D) selection.elementAt(i);
|
// selectee.ReverseTriangles();
|
// }
|
|
//Touch();
|
}
|
|
void GenUVs()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
GenUVs0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.GenUVs();
|
// Children().release(i);
|
}
|
blockloop = false;
|
}
|
|
void GenNormals(boolean crease)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
GenNormals0(crease);
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.GenNormals(crease);
|
// Children().release(i);
|
}
|
blockloop = false;
|
}
|
|
void GenNormalsMesh()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
GenNormalsMesh0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.GenNormalsMesh();
|
// Children().release(i);
|
}
|
blockloop = false;
|
}
|
|
void GenNormalsMINE()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
GenNormalsMINE0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.GenNormalsMINE();
|
// Children().release(i);
|
}
|
blockloop = false;
|
}
|
|
void ClearColors()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
ClearColors0();
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.ClearColors();
|
// Children().release(i);
|
}
|
blockloop = false;
|
}
|
|
void Stripify()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
Stripify0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.Stripify();
|
// Children().release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void Unstripify()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
Unstripify0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.Unstripify();
|
// Children().release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ReverseNormals()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
ReverseNormals0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.ReverseNormals();
|
// Children().release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void Parse(iParse obj)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
Parse0(obj);
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.Parse(obj);
|
// Children().release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ReverseTriangles()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
ReverseTriangles0();
|
for (int i = 0; i < Children().Size(); i++)
|
{
|
Object3D child = (Object3D) Children().get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.ReverseTriangles();
|
// Children().release(i);
|
}
|
|
blockloop = false;
|
}
|
|
|
void GenUVs0()
|
{
|
if (bRep != null)
|
{
|
bRep.GenUV(); //1);
|
//bRep.UnfoldUV();
|
Touch();
|
}
|
}
|
|
void GenNormals0(boolean crease)
|
{
|
if (bRep != null)
|
{
|
//bRep.GenerateNormals2(crease); // in-place doesn't work. it gives wrong normals (diamond artifact).
|
bRep.GenerateNormals(crease);
|
if (!bRep.trimmed)
|
bRep.MergeNormals();
|
Touch();
|
}
|
}
|
|
void GenNormalsMesh0()
|
{
|
if (bRep != null)
|
{
|
bRep.GenerateNormalsMesh();
|
Touch();
|
}
|
}
|
|
void GenNormalsMINE0()
|
{
|
if (bRep != null)
|
{
|
bRep.MergeNormals(); //.GenerateNormalsMINE();
|
Touch();
|
}
|
}
|
|
static double[][] tempmat = LA.newMatrix();
|
|
transient double[][] texturemat;
|
|
void KeepTextureMatrices()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
texturemat = null;
|
|
if (this instanceof Texture || this instanceof TextureNode)
|
{
|
texturemat = toParent;
|
toParent = null;
|
}
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D v = get(i);
|
|
v.KeepTextureMatrices();
|
}
|
|
blockloop = false;
|
}
|
|
void RestoreTextureMatrices()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (this instanceof Texture || this instanceof TextureNode)
|
{
|
toParent = texturemat;
|
texturemat = null;
|
}
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D v = get(i);
|
|
v.RestoreTextureMatrices();
|
}
|
|
blockloop = false;
|
}
|
|
public void ResetTransform(int mask)
|
{
|
Object3D obj = this;
|
|
if (mask == -1)
|
{
|
if (obj instanceof Camera) // jan 2014
|
{
|
LA.matIdentity(obj.toParent);
|
LA.matIdentity(obj.fromParent);
|
}
|
else
|
{
|
obj.toParent = null; // jan 2014 LA.matIdentity(obj.toParent);
|
obj.fromParent = null; // LA.matIdentity(obj.fromParent);
|
}
|
return;
|
}
|
|
if ((mask&2) != 0) // Scale/rotation
|
{
|
obj.toParent[0][0] = obj.toParent[1][1] = obj.toParent[2][2] = 1;
|
obj.toParent[0][1] = obj.toParent[1][0] = obj.toParent[2][0] = 0;
|
obj.toParent[0][2] = obj.toParent[1][2] = obj.toParent[2][1] = 0;
|
obj.fromParent[0][0] = obj.fromParent[1][1] = obj.fromParent[2][2] = 1;
|
obj.fromParent[0][1] = obj.fromParent[1][0] = obj.fromParent[2][0] = 0;
|
obj.fromParent[0][2] = obj.fromParent[1][2] = obj.fromParent[2][1] = 0;
|
}
|
if ((mask&1) != 0) // Translation
|
{
|
if (obj.toParent != null)
|
{
|
obj.toParent[3][0] = obj.toParent[3][1] = obj.toParent[3][2] = 0;
|
obj.fromParent[3][0] = obj.fromParent[3][1] = obj.fromParent[3][2] = 0;
|
}
|
}
|
}
|
|
public void Scale(int scale)
|
{
|
Object3D obj = this;
|
|
obj.toParent[0][0] = obj.toParent[1][1] = obj.toParent[2][2] = scale;
|
obj.toParent[0][1] = obj.toParent[1][0] = obj.toParent[2][0] = 0;
|
obj.toParent[0][2] = obj.toParent[1][2] = obj.toParent[2][1] = 0;
|
obj.fromParent[0][0] = obj.fromParent[1][1] = obj.fromParent[2][2] = 1/scale;
|
obj.fromParent[0][1] = obj.fromParent[1][0] = obj.fromParent[2][0] = 0;
|
obj.fromParent[0][2] = obj.fromParent[1][2] = obj.fromParent[2][1] = 0;
|
}
|
|
public void TextureRatioTransform(int axis)
|
{
|
cTexture tex = GetTextures();
|
|
com.sun.opengl.util.texture.TextureData texturedata = null;
|
|
try
|
{
|
texturedata = Globals.theRenderer.GetTextureData(tex, false, texres);
|
}
|
catch (Exception e)
|
{
|
System.err.println("FAIL TextureRatio: " + this);
|
}
|
|
LA.matIdentity(Object3D.mat);
|
Object3D.mat[axis][axis] = (double)texturedata.getWidth() / texturedata.getHeight();
|
|
if (toParent == null)
|
{
|
toParent = LA.newMatrix();
|
fromParent = LA.newMatrix();
|
}
|
|
ResetTransform(2);
|
|
LA.matConcat(Object3D.mat, fromParent, fromParent);
|
LA.matInvert(fromParent, toParent);
|
}
|
|
void TextureRatio(int axis)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
TextureRatioTransform(axis);
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D v = get(i);
|
|
v.TextureRatio(axis);
|
}
|
|
blockloop = false;
|
}
|
|
void TransformChildren()
|
{
|
if (toParent != null)
|
{
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D v = get(i);
|
|
if (v.toParent == null)
|
{
|
v.toParent = LA.newMatrix();
|
v.fromParent = LA.newMatrix();
|
}
|
|
// LA.matConcat(v.toParent, toParent, v.toParent);
|
// LA.matConcat(fromParent, v.fromParent, v.fromParent);
|
LA.matConcat(toParent, v.toParent, v.toParent);
|
LA.matConcat(v.fromParent, fromParent, v.fromParent);
|
}
|
|
toParent = null; // LA.matIdentity(toParent);
|
fromParent = null; // LA.matIdentity(fromParent);
|
|
Touch();
|
}
|
}
|
|
void TransformGeometry()
|
{
|
Object3D obj = this;
|
|
// if (obj.toParent == null)
|
// return;
|
|
if (obj.bRep != null)
|
{
|
if (obj.toParent != null)
|
for (int i=obj.bRep.VertexCount(); --i>=0;)
|
{
|
Vertex v = obj.bRep.GetVertex(i);
|
|
LA.xformPos(v, obj.toParent, v);
|
LA.matTranspose(obj.fromParent, tempmat);
|
//LA.xformPos(v.norm, obj.toParent, v.norm); // "RIGID"
|
if (v.norm != null) // nov 2013
|
LA.xformPos(v.norm, tempmat, v.norm);
|
|
obj.bRep.SetVertex(v, i);
|
}
|
|
obj.toParent = null; // LA.matIdentity(obj.toParent);
|
obj.fromParent = null; // LA.matIdentity(obj.fromParent);
|
|
obj.Touch();
|
}
|
else
|
{
|
for (int i=obj.Size(); --i>=0;)
|
{
|
Object3D v = obj.get(i);
|
|
//if (!(obj instanceof Texture) && !(v instanceof Texture))
|
{
|
if (v.toParent == null)
|
{
|
v.toParent = LA.newMatrix();
|
v.fromParent = LA.newMatrix();
|
}
|
|
if (obj.toParent != null)
|
{
|
LA.matConcat(v.toParent, obj.toParent, v.toParent);
|
LA.matConcat(obj.fromParent, v.fromParent, v.fromParent);
|
}
|
}
|
|
v.TransformGeometry();
|
}
|
|
//if (!(obj instanceof Texture))
|
{
|
obj.toParent = null; // LA.matIdentity(obj.toParent);
|
obj.fromParent = null; // LA.matIdentity(obj.fromParent);
|
|
obj.Touch();
|
}
|
}
|
}
|
|
static boolean AOdone = false;
|
|
void Stripify0()
|
{
|
//AOdone = false;
|
if (bRep != null)
|
{
|
try
|
{
|
bRep.Stripify();
|
}
|
catch (Exception e)
|
{
|
System.err.println("STRIP FAILS: " + this);
|
e.printStackTrace();
|
System.err.println("STRIP FAILS: " + this);
|
}
|
Touch();
|
}
|
}
|
|
void Unstripify0()
|
{
|
//AOdone = false;
|
if (bRep != null)
|
{
|
try
|
{
|
bRep.Unstripify();
|
}
|
catch (Exception e)
|
{
|
System.err.println("UNSTRIP FAILS: " + this);
|
e.printStackTrace();
|
System.err.println("UNSTRIP FAILS: " + this);
|
}
|
Touch();
|
}
|
}
|
|
void Trim()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
bRep.Trim();
|
Touch();
|
}
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.Trim();
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void Untrim()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
bRep.Untrim();
|
Touch();
|
}
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.Untrim();
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ClearColors0()
|
{
|
AOdone = false;
|
if (bRep != null)
|
{
|
bRep.ClearColors();
|
Touch();
|
}
|
}
|
|
void ReverseNormals0()
|
{
|
if (bRep != null)
|
{
|
bRep.ReverseNormals();
|
Touch();
|
}
|
}
|
|
void Parse0(iParse obj)
|
{
|
if (bRep != null)
|
{
|
//bRep.Parse(obj);
|
|
for (int i = 0; i < bRep.VertexCount(); i++)
|
{
|
Vertex v = bRep.GetVertex(i);
|
obj.Vertex(this, v);
|
}
|
|
if (!bRep.stripified)
|
{
|
for (int i = 0; i < bRep.FaceCount(); i++)
|
{
|
Face f = bRep.GetFace(i);
|
obj.Face(this, f);
|
}
|
}
|
|
Touch();
|
}
|
}
|
|
void ReverseTriangles0()
|
{
|
if (bRep != null)
|
{
|
bRep.ReverseTriangles();
|
Touch();
|
}
|
}
|
|
void ReduceMesh(boolean reduction34, boolean onlyone)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
//bRep.RemoveOneTriangle();
|
System.out.println();
|
System.out.println("Reducing " + this);
|
if (name != null && name.contains("lockpickstraps"))
|
name = name;
|
|
BoundaryRep sup = bRep.support;
|
bRep.support = null;
|
BoundaryRep temprep = (BoundaryRep) Grafreed.clone(bRep);
|
// bRep.SplitInTwo(onlyone); // thread...
|
|
while(temprep.SplitInTwo(reduction34, onlyone));
|
|
bRep = temprep;
|
bRep.support = sup;
|
Touch();
|
}
|
else
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.ReduceMesh(reduction34, onlyone);
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void IncreaseMesh()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
//bRep.RemoveOneTriangle();
|
System.out.println("Increasing " + this);
|
bRep.IncreaseMesh();
|
Touch();
|
}
|
else
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.IncreaseMesh();
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ClipMesh(Object3D clip)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
//bRep.RemoveOneTriangle();
|
System.out.println("Clipping " + this);
|
bRep.ClipMesh(clip, GlobalTransformInv());
|
Touch();
|
}
|
else
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.ClipMesh(clip);
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void SmoothMesh()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
if (bRep != null)
|
{
|
//bRep.RemoveOneTriangle();
|
System.out.println("Smoothing " + this);
|
bRep.SmoothMesh();
|
Touch();
|
}
|
else
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.SmoothMesh();
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ClearMaterials()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
ClearMaterial();
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
child.ClearMaterials();
|
}
|
|
blockloop = false;
|
}
|
|
void ClearVersionList()
|
{
|
this.versionlist = null;
|
this.versionindex = -1;
|
this.versiontable = null;
|
}
|
|
void ClearVersions()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
ClearVersionList();
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
child.ClearVersions();
|
}
|
|
blockloop = false;
|
}
|
|
void FlipV(boolean flip)
|
{
|
flipV = flip;
|
Touch();
|
|
if (blockloop)
|
return;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.FlipV(flip);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void LiveLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
if (//marked || // does not make sense
|
(bRep != null || material != null)) // borderline...
|
live = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.LiveLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void SupportLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
//if (bRep != null)
|
if (//marked || // does not make sense
|
(bRep != null || material != null)) // borderline...
|
link2master = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.SupportLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void HideLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
if (//marked || // does not make sense
|
(bRep != null || material != null)) // borderline...
|
hide = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.HideLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void MarkLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
if (bRep != null || material != null) // borderline...
|
marked = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.MarkLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void RewindLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
if (bRep != null || material != null) // borderline...
|
rewind = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.RewindLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void RandomLeaves(boolean h)
|
{
|
if (blockloop)
|
return;
|
|
if (bRep != null || material != null) // borderline...
|
random = h;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
blockloop = true;
|
child.RandomLeaves(h);
|
blockloop = false;
|
// release(i);
|
}
|
}
|
|
void SetTexRes(int tr)
|
{
|
texres = tr;
|
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
if (child == null)
|
continue;
|
child.SetTexRes(tr);
|
release(i);
|
}
|
}
|
|
//transient
|
BoundaryRep transientrep = null;
|
|
BoundaryRep GetBRep()
|
{
|
if (bRep == null)
|
return transientrep;
|
|
return bRep;
|
}
|
|
void Revert()
|
{
|
// assert(false);
|
}
|
|
void RevertMeshes()
|
{
|
// BLOCKLOOP
|
if (this instanceof cMesh)
|
{
|
((cMesh)this).Revert();
|
Touch();
|
}
|
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
|
if (child == null)
|
continue;
|
|
child.RevertMeshes();
|
release(i);
|
}
|
}
|
|
void ResetAll()
|
{
|
if (blockloop)
|
return;
|
|
//if (this instanceof cMesh)
|
{
|
//((cMesh)this).
|
Reset();
|
Touch();
|
}
|
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.ResetAll();
|
blockloop = false;
|
//release(i);
|
}
|
}
|
|
void StepAll()
|
{
|
if (blockloop)
|
return;
|
|
Step();
|
Touch();
|
|
StepRecur();
|
}
|
|
void StepRecur()
|
{
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.StepAll();
|
blockloop = false;
|
//release(i);
|
}
|
}
|
|
void ClearList()
|
{
|
if (bRep != null)
|
{
|
if (bRep.displaylist > 0)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
}
|
bRep.displaylist = 0; // june 2013 -1;
|
Touch();
|
}
|
}
|
|
void retile()
|
{
|
retile(false);
|
}
|
|
void retile(boolean forced)
|
{
|
}
|
|
void recalculate()
|
{
|
Touch();
|
}
|
|
void generatePOV(StringBuffer buffer)
|
{
|
generateNameComment(buffer);
|
}
|
|
void generateNameComment(StringBuffer buffer)
|
{
|
generateIndent(buffer);
|
buffer.append("// ");
|
buffer.append(name);
|
buffer.append("\n");
|
}
|
|
void generateTransform(StringBuffer buffer)
|
{
|
if (LA.isIdentity(toParent))
|
{
|
generateIndent(buffer);
|
buffer.append(" // identity transformation\n");
|
} else
|
{
|
povDepth += 4;
|
generateIndent(buffer);
|
buffer.append("matrix <\n");
|
povDepth += 4;
|
for (int i = 0; i < 4; i++)
|
{
|
generateIndent(buffer);
|
for (int j = 0; j < 3; j++)
|
{
|
buffer.append(toParent[i][j]);
|
if (i != 3 || j != 2)
|
{
|
buffer.append(", ");
|
}
|
}
|
|
buffer.append("\n");
|
}
|
|
povDepth -= 4;
|
generateIndent(buffer);
|
buffer.append(">\n");
|
povDepth -= 4;
|
}
|
}
|
|
void generateIndent(StringBuffer buffer)
|
{
|
for (int i = 0; i < povDepth; i++)
|
{
|
buffer.append(' ');
|
}
|
|
}
|
|
void getAverage(cVector average, boolean xform)
|
{
|
average.set(0,0,0);
|
|
BoundaryRep usedrep = bRep;
|
|
if (usedrep == null)
|
usedrep = transientrep;
|
|
if (usedrep == null)
|
return;
|
|
for (int i = 0; i < usedrep.VertexCount(); i++)
|
{
|
Vertex v = usedrep.GetVertex(i);
|
|
average.add(v);
|
}
|
|
average.mul(1.0/usedrep.VertexCount());
|
|
if (xform)
|
{
|
LA.xformPos(average, toParent, average);
|
}
|
}
|
|
void getAverage(cVector average, boolean xform, double distance)
|
{
|
cStatic.point2.set(0,0,0);
|
|
if (bRep == null)
|
{
|
return;
|
}
|
|
int count = 0;
|
|
for (int i = 0; i < bRep.VertexCount(); i++)
|
{
|
Vertex v = bRep.GetVertex(i);
|
|
cStatic.point1.set(v);
|
cStatic.point1.sub(average); // means anchor
|
|
if (cStatic.point1.dot(cStatic.point1) > distance*distance)
|
continue;
|
|
count++;
|
cStatic.point2.add(v);
|
}
|
|
if (count > 0)
|
cStatic.point2.mul(1.0/count);
|
|
if (xform)
|
{
|
LA.xformPos(cStatic.point2, toParent, cStatic.point2);
|
}
|
|
average.set(cStatic.point2);
|
}
|
|
void TransformMesh(double[][] t)
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
for (int i=Size(); --i>=0;)
|
{
|
Object3D obj = get(i);
|
|
obj.TransformMesh(t);
|
}
|
|
blockloop = false;
|
|
if (bRep == null)
|
{
|
return;
|
}
|
|
bRep.Transform(t);
|
|
Touch();
|
}
|
|
transient cVector min;
|
transient cVector max;
|
|
void getBounds(cVector minima, cVector maxima, boolean xform)
|
{
|
if (name != null && name.contains("Geometry:Mesh:Body"))
|
name = name;
|
|
minima.x = minima.y = minima.z = Double.POSITIVE_INFINITY;
|
maxima.x = maxima.y = maxima.z = Double.NEGATIVE_INFINITY;
|
|
// cVector min = new cVector();
|
// cVector max = new cVector();
|
//
|
if (blockloop)
|
return;
|
|
if (min == null)
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
for (int i = 0; i<Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); //reserve(i);
|
if (child == null)
|
continue;
|
|
if (Grafreed.RENDERME > 0)
|
{
|
if (child instanceof Merge)
|
((Merge)child).renderme();
|
|
if (child instanceof SwitchNode)
|
((SwitchNode)child).Update();
|
|
if (child.NeedSupport())
|
child.resetMasterNode(false); // live);
|
}
|
|
if (child.hide && !(child instanceof Merge) || child.skip)
|
//if (child.hide)
|
{
|
//release(i);
|
continue;
|
}
|
|
blockloop = true;
|
child.getBounds(min, max, true); // xform);
|
blockloop = false;
|
//release(i);
|
|
MinMax(minima, maxima);
|
}
|
|
if (bRep != null)
|
{
|
bRep.getBounds(minima, maxima, xform?this:null);
|
}
|
|
if (false) // xform)
|
{
|
transformBounds(minima, maxima);
|
}
|
}
|
|
boolean getCentroid(cVector centroid, boolean xform)
|
{
|
// for speaker assert(false);
|
if (blockloop)
|
return false;
|
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
centroid.x = centroid.y = centroid.z = 0;
|
|
int count = 0;
|
|
if (size() > 0)
|
{
|
for (int i = size(); --i >= 0;)
|
{
|
Object3D child = (Object3D) reserve(i);
|
if (child == null)
|
continue;
|
if (child.hide && !(child instanceof Merge) || child.skip) // || child.size() == 0)
|
{
|
release(i);
|
continue;
|
}
|
|
blockloop = true;
|
boolean success = child.getCentroid(min, true); // xform);
|
blockloop = false;
|
release(i);
|
|
if (!success)
|
continue;
|
|
count++;
|
centroid.x += min.x;
|
centroid.y += min.y;
|
centroid.z += min.z;
|
}
|
|
if (count == 0)
|
return false; // fail
|
|
assert(count > 0);
|
{
|
centroid.x /= count;
|
centroid.y /= count;
|
centroid.z /= count;
|
}
|
}
|
|
if (bRep != null)
|
{
|
bRep.getCentroid(min, null);
|
|
if (count > 0)
|
{
|
// ???
|
assert(false);
|
centroid.x += min.x; centroid.x /= 2;
|
centroid.y += min.y; centroid.y /= 2;
|
centroid.z += min.z; centroid.z /= 2;
|
}
|
else
|
centroid.set(min);
|
}
|
else
|
{
|
//assert(count > 0);
|
if (count == 0)
|
return false;
|
}
|
|
if (xform && !(this instanceof Texture || this instanceof TextureNode))
|
{
|
for (int loop=GetTransformCount(); --loop>=0;)
|
{
|
LA.xformPos(centroid, toParent, centroid);
|
}
|
//LA.xformPos(centroid, toParent, centroid);
|
}
|
|
return true;
|
}
|
|
boolean getCentroid(cVector centroid) //, Object3D root)
|
{
|
if (blockloop)
|
return false;
|
|
//GraphreeD.tracein(this);
|
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
centroid.x = centroid.y = centroid.z = 0;
|
|
int count = 0;
|
|
if (size() > 0)
|
{
|
for (int i=0; i<size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
if (child == null)
|
continue;
|
|
if (Grafreed.RENDERME > 0)
|
{
|
if (child instanceof Merge)
|
((Merge)child).renderme();
|
|
if (child instanceof SwitchNode)
|
((SwitchNode)child).Update();
|
|
if (child.NeedSupport())
|
child.resetMasterNode(false); // live);
|
}
|
|
if (child.hide && !(child instanceof Merge) || child.skip) // || child.size() == 0)
|
{
|
release(i);
|
continue;
|
}
|
|
blockloop = true;
|
boolean success = child.getCentroid(min); // , this); // xform);
|
blockloop = false;
|
release(i);
|
|
if (!success)
|
continue;
|
|
count++;
|
centroid.x += min.x;
|
centroid.y += min.y;
|
centroid.z += min.z;
|
}
|
|
if (count == 0)
|
return false; // fail
|
|
assert(count > 0);
|
{
|
centroid.x /= count;
|
centroid.y /= count;
|
centroid.z /= count;
|
}
|
}
|
|
if (bRep != null)
|
{
|
bRep.getCentroid(min, this);
|
|
if (count > 0)
|
{
|
// ???
|
assert(false);
|
centroid.x += min.x; centroid.x /= 2;
|
centroid.y += min.y; centroid.y /= 2;
|
centroid.z += min.z; centroid.z /= 2;
|
}
|
else
|
centroid.set(min);
|
|
// if (root != null && !(this instanceof Texture))
|
// {
|
// root.TransformToWorld(centroid);
|
// }
|
}
|
else
|
{
|
//assert(count > 0);
|
if (count == 0)
|
return false;
|
}
|
|
//GraphreeD.traceout(this, centroid);
|
|
return true;
|
}
|
|
boolean getFloor(cVector floor, boolean xform)
|
{
|
assert(false);
|
|
if (blockloop)
|
return false;
|
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
floor.x = floor.z = 0; //
|
floor.y = Float.MAX_VALUE;
|
|
int count = 0;
|
|
if (size0() > 0)
|
{
|
for (int i = size0(); --i >= 0;)
|
{
|
Object3D child = (Object3D) reserve0(i);
|
if (child == null)
|
continue;
|
if (child.hide && !(child instanceof Merge) || child.skip) // || child.size() == 0)
|
{
|
release(i);
|
continue;
|
}
|
blockloop = true;
|
boolean success = child.getFloor(min, true); // xform);
|
blockloop = false;
|
release(i);
|
|
if (!success)
|
continue;
|
|
count++;
|
if (floor.y > min.y)
|
{
|
floor.y = min.y;
|
floor.x = min.x;
|
floor.z = min.z;
|
}
|
}
|
|
if (count == 0)
|
return false; // fail
|
//
|
// assert(count > 0);
|
// {
|
// centroid.x /= count;
|
// centroid.z /= count;
|
// }
|
}
|
|
if (bRep != null)
|
{
|
bRep.getFloor(min);
|
|
// if (count > 0)
|
// {
|
// // ???
|
// assert(false);
|
// centroid.x += min.x; centroid.x /= 2;
|
// centroid.y += min.y; centroid.y /= 2;
|
// centroid.z += min.z; centroid.z /= 2;
|
// }
|
// else
|
floor.set(min);
|
}
|
else
|
{
|
//assert(count > 0);
|
if (count == 0)
|
return false;
|
}
|
|
if (xform && !(this instanceof Texture || this instanceof TextureNode))
|
{
|
for (int loop=GetTransformCount(); --loop>=0;)
|
{
|
LA.xformPos(floor, toParent, floor);
|
}
|
// LA.xformPos(centroid, toParent, centroid);
|
}
|
|
return true;
|
}
|
|
long getFloor(cVector floor) //, Object3D root)
|
{
|
if (blockloop)
|
return 0;
|
|
long ID = 0;
|
|
//GraphreeD.tracein(this);
|
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
floor.x = floor.z = 0; //
|
floor.y = Float.MAX_VALUE;
|
|
int count = 0;
|
|
if (size/*0*/() > 0)
|
{
|
//for (int i = size/*0*/(); --i >= 0;)
|
for (int i=0; i<size(); i++)
|
{
|
Object3D child = (Object3D) reserve/*0*/(i);
|
if (child == null)
|
continue;
|
|
if (Grafreed.RENDERME > 0)
|
{
|
if (child instanceof Merge)
|
((Merge)child).renderme();
|
|
if (child instanceof SwitchNode)
|
((SwitchNode)child).Update();
|
|
if (child.NeedSupport())
|
child.resetMasterNode(false); // live);
|
}
|
|
if (child.hide && !(child instanceof Merge/*Mocap??*/) /* && !child.live may 2014 */ || child.skip) // || child.size() == 0)
|
{
|
release(i);
|
continue;
|
}
|
|
blockloop = true;
|
long floorid = child.getFloor(min); //, this); // xform);
|
blockloop = false;
|
release(i);
|
|
if (floorid == 0) // !success)
|
continue;
|
|
count++;
|
if (floor.y > min.y)
|
{
|
ID = floorid * System.identityHashCode(child);
|
|
floor.y = min.y;
|
floor.x = min.x;
|
floor.z = min.z;
|
}
|
}
|
|
//Dump(true);
|
|
if (count == 0)
|
return 0; // fail
|
//
|
// assert(count > 0);
|
// {
|
// centroid.x /= count;
|
// centroid.z /= count;
|
// }
|
}
|
|
boolean retval = true;
|
|
if (bRep != null)
|
{
|
ID = bRep.getFloor(min, this);
|
|
// if (count > 0)
|
// {
|
// // ???
|
// assert(false);
|
// centroid.x += min.x; centroid.x /= 2;
|
// centroid.y += min.y; centroid.y /= 2;
|
// centroid.z += min.z; centroid.z /= 2;
|
// }
|
// else
|
floor.set(min);
|
|
// if (root != null && !(this instanceof Texture))
|
// {
|
// root.TransformToWorld(floor);
|
// }
|
}
|
else
|
{
|
//assert(count > 0);
|
if (count == 0)
|
ID = 0; // retval = false;
|
}
|
|
//GraphreeD.traceout(this, floor);
|
|
return ID; // retval;
|
}
|
|
void RepairParent()
|
{
|
if (blockloop)
|
return;
|
|
for (int i=0; i<Size(); i++)
|
{
|
if (get(i).parent != this)
|
{
|
System.err.println(get(i) + ": parent mismatch! " + ((get(i).parent == null)?"NULL":get(i).parent.GetPath()) + " vs " + GetPath());
|
get(i).parent = this;
|
}
|
blockloop = true;
|
get(i).RepairParent();
|
blockloop = false;
|
}
|
}
|
|
void RepairShadow()
|
{
|
if (blockloop)
|
return;
|
|
if (this.material != null)
|
this.InitOthers();
|
|
for (int i=0; i<Size(); i++)
|
{
|
blockloop = true;
|
get(i).RepairShadow();
|
blockloop = false;
|
}
|
}
|
|
void RepairSOV()
|
{
|
if (blockloop)
|
return;
|
|
String texname = this.GetPigmentTexture();
|
|
if (texname.startsWith("sov"))
|
{
|
String[] s = texname.split("/");
|
|
String[] sname = s[1].split("Color.pn");
|
|
texname = sname[0];
|
|
if (sname.length > 1)
|
{
|
texname += "Color.jpg";
|
}
|
|
this.SetPigmentTexture("sov/" + texname);
|
}
|
|
texname = this.GetBumpTexture();
|
|
if (texname.startsWith("sov"))
|
{
|
String[] s = texname.split("/");
|
|
String[] sname = s[1].split("Bump.pn");
|
|
texname = sname[0];
|
|
if (sname.length > 1)
|
{
|
texname += "Bump.jpg";
|
}
|
|
this.SetBumpTexture("sov/" + texname);
|
}
|
|
for (int i=0; i<Size(); i++)
|
{
|
blockloop = true;
|
get(i).RepairSOV();
|
blockloop = false;
|
}
|
}
|
|
void RepairTexture()
|
{
|
if (this instanceof FileObject || blockloop)
|
return;
|
|
for (int i=0; i<size(); i++)
|
{
|
Object3D child = get(i);
|
|
boolean replace = false;
|
|
if (child instanceof Texture)
|
{
|
replace = true;
|
Texture childtex = (Texture) child;
|
TextureNode tex = new TextureNode();
|
tex.name = childtex.name;
|
tex.toParent = childtex.toParent;
|
tex.fromParent = childtex.fromParent;
|
tex.maxcount = childtex.maxcount;
|
tex.transformcount = childtex.transformcount;
|
tex.step = childtex.step;
|
for (int j=0; j<child.size(); j++)
|
{
|
tex.addChild(child.get(j));
|
}
|
child = tex;
|
}
|
|
blockloop = true;
|
child.RepairTexture();
|
blockloop = false;
|
|
// try
|
// {
|
if (replace)
|
set(i, child);
|
// }
|
// catch (Exception e)
|
// {
|
// e.printStackTrace();
|
// }
|
}
|
}
|
|
// int GetTransformCount()
|
// {
|
// return 1;
|
// }
|
|
void transformBounds(cVector minima, cVector maxima)
|
{
|
if (this instanceof Texture || this instanceof TextureNode)
|
{
|
return;
|
}
|
//for (int i=0; i < 3; i++)
|
{
|
tbMin.x = tbMin.y = tbMin.z = Double.POSITIVE_INFINITY; // ??? 1E+10;
|
tbMax.x = tbMax.y = tbMax.z = Double.NEGATIVE_INFINITY; // -1E+10;
|
}
|
|
if (minima.x == Double.POSITIVE_INFINITY) // 1E10)
|
{
|
return;
|
}
|
|
for (int i = 0; i < 8; i++)
|
{
|
tbIn.x = i >= 4 ? maxima.x : minima.x;
|
tbIn.y = (i / 2) % 2 != 0 ? maxima.y : minima.y;
|
tbIn.z = i % 2 != 0 ? maxima.z : minima.z;
|
// tbOut.set(tbIn);
|
for (int loop=GetTransformCount(); --loop>=0;)
|
{
|
LA.xformPos(tbIn, toParent, tbIn); // Out);
|
//tbIn.set(tbOut);
|
}
|
tbOut.set(tbIn); //
|
for (int j = 0; j < 3; j++)
|
{
|
if (tbOut.get(j) < tbMin.get(j))
|
{
|
tbMin.set(j, tbOut.get(j));
|
}
|
if (tbOut.get(j) > tbMax.get(j))
|
{
|
tbMax.set(j, tbOut.get(j));
|
}
|
}
|
|
}
|
|
LA.vecCopy(tbMin, minima);
|
LA.vecCopy(tbMax, maxima);
|
}
|
|
void untransform(double x, double y, double z, cVector pnt)
|
{
|
if (fromParent == null) // aout 2013
|
{
|
pnt.x = x;
|
pnt.y = y;
|
pnt.z = z;
|
return;
|
}
|
|
pnt.x = x * fromParent[0][0] + y * fromParent[1][0] + z * fromParent[2][0] + fromParent[3][0];
|
pnt.y = x * fromParent[0][1] + y * fromParent[1][1] + z * fromParent[2][1] + fromParent[3][1];
|
pnt.z = x * fromParent[0][2] + y * fromParent[1][2] + z * fromParent[2][2] + fromParent[3][2];
|
}
|
|
static Vertex[] vv = new Vertex[0];
|
|
static class FaceInfo
|
{
|
cVector normal = new cVector();
|
cVector pqnormal = new cVector();
|
cVector qrnormal = new cVector();
|
cVector rpnormal = new cVector();
|
|
Vertex p;
|
}
|
|
transient FaceInfo[] faces = null;
|
|
boolean insideMesh(double x, double y, double z, boolean untransform)
|
{
|
if (count <= 0)
|
{
|
return false;
|
}
|
|
// sept 2013
|
if (true)
|
{
|
if (untransform)
|
{
|
untransform(x, y, z, v0);
|
} else
|
{
|
LA.setVector(v0, x, y, z);
|
}
|
|
return bRep.inside(v0, this);
|
}
|
|
if (bRep == null)
|
{
|
System.out.println("INSIDE NULL OBJECT");
|
return false;
|
} else
|
{
|
if (faces == null || faces.length != bRep.FaceCount() /*???*/)
|
{
|
faces = new FaceInfo[bRep.FaceCount()];
|
|
for (int i = bRep.FaceCount(); --i >= 0;)
|
{
|
FaceInfo fi = faces[i] = new FaceInfo();
|
|
Face f = bRep.GetFace(i);
|
|
if (f == null)
|
f = null;
|
|
fi.p = bRep.GetVertex(f.p);
|
Vertex q = bRep.GetVertex(f.q);
|
Vertex r = bRep.GetVertex(f.r);
|
|
LA.vecSub(q, fi.p, v2);
|
LA.vecSub(r, fi.p, v3);
|
LA.vecCross(v2, v3, fi.normal);
|
LA.vecCross(fi.p, q, fi.pqnormal);
|
LA.vecCross(q, r, fi.qrnormal);
|
LA.vecCross(r, fi.p, fi.rpnormal);
|
}
|
}
|
|
if (untransform)
|
{
|
untransform(x, y, z, v0);
|
} else
|
{
|
LA.setVector(v0, x, y, z);
|
}
|
|
boolean inside = true;
|
|
for (int i = bRep.FaceCount(); --i >= 0;)
|
{
|
FaceInfo f = faces[i];
|
|
boolean ins = true;
|
|
//LA.vecSub(f.p, v0, v5);
|
v5.x = v0.x - f.p.x;
|
v5.y = v0.y - f.p.y;
|
v5.z = v0.z - f.p.z;
|
|
//if (v5.dot(f.normal) > 0)
|
if (v5.x*f.normal.x + v5.y*f.normal.y + v5.z*f.normal.z > 0)
|
{
|
ins = false;
|
}
|
// else
|
// {
|
// //if (f.pqnormal.dot(v0) < 0)
|
// if (f.pqnormal.x*v0.x + f.pqnormal.y*v0.y + f.pqnormal.z*v0.z < 0)
|
// {
|
// ins = false;
|
// } else
|
// {
|
// //if (f.qrnormal.dot(v0) < 0)
|
// if (f.qrnormal.x*v0.x + f.qrnormal.y*v0.y + f.qrnormal.z*v0.z < 0)
|
// {
|
// ins = false;
|
// } else
|
// {
|
// //if (f.rpnormal.dot(v0) < 0)
|
// if (f.rpnormal.x*v0.x + f.rpnormal.y*v0.y + f.rpnormal.z*v0.z < 0)
|
// {
|
// ins = false;
|
// }
|
// }
|
// }
|
// }
|
|
// inside ^= ins;
|
|
if (!ins)
|
{
|
inside = false;
|
break;
|
}
|
}
|
|
return inside;
|
}
|
}
|
|
boolean insideMesh0(double x, double y, double z, boolean untransform)
|
{
|
if (count <= 0)
|
{
|
return false;
|
}
|
|
if (bRep == null)
|
{
|
System.out.println("INSIDE NULL OBJECT");
|
return false;
|
} else
|
{
|
int j = bRep.VertexCount();
|
if (vv.length < j)
|
{
|
vv = new Vertex[j];
|
}
|
|
for (; --j >= 0;)
|
{
|
vv[j] = bRep.GetVertex(j);
|
}
|
|
if (untransform)
|
{
|
untransform(x, y, z, v0);
|
} else
|
{
|
LA.setVector(v0, x, y, z);
|
}
|
|
boolean inside = false;
|
|
for (int i = bRep.FaceCount(); --i >= 0;)
|
{
|
Face f = bRep.GetFace(i);
|
|
Vertex p = vv[f.p];
|
Vertex q = vv[f.q];
|
Vertex r = vv[f.r];
|
|
boolean ins = true;
|
|
LA.vecSub(p, r, v2);
|
LA.vecSub(p, q, v3);
|
LA.vecCross(v2, v3, v4);
|
LA.vecSub(p, v0, v5);
|
//LA.vecSub(q,v0, v6);
|
//LA.vecSub(r,v0, v7);
|
if (v5.dot(v4) > 0)
|
{
|
ins = false;
|
} else
|
{
|
LA.vecCross(p, q, v1);
|
if (v1.dot(v0) < 0) // ^ v1.dot(r) < 0)
|
{
|
ins = false;
|
} else
|
{
|
LA.vecCross(q, r, v1);
|
if (v1.dot(v0) < 0) // ^ v1.dot(p) < 0)
|
{
|
ins = false;
|
} else
|
{
|
LA.vecCross(r, p, v1);
|
if (v1.dot(v0) < 0) // ^ v1.dot(q) < 0)
|
{
|
ins = false;
|
}
|
}
|
}
|
}
|
|
inside ^= ins;
|
}
|
|
return inside;
|
}
|
}
|
|
void boxInside(double x[], double y[], double z[], boolean aflag[])
|
{
|
}
|
|
|
boolean inside(double x, double y, double z, boolean xform)
|
{
|
if (count <= 0)
|
{
|
return false;
|
}
|
|
// assert(xform);
|
//System.out.println("inside = " + x + ", " + y + ", " + z);
|
if (xform && fromParent != null)
|
{
|
untransform(x, y, z, cStatic.point1);
|
x = cStatic.point1.x;
|
y = cStatic.point1.y;
|
z = cStatic.point1.z;
|
}
|
|
boolean inside = false;
|
|
if (bRep != null)
|
{
|
if (insideMesh(x,y,z, true))
|
{
|
return true;
|
}
|
}
|
|
for (int i = Children().size() - 1; i >= 0; i--)
|
{
|
Object3D child = (Object3D) Children().reserve(i);
|
if (child == null)
|
continue;
|
if (child.inside(x, y, z, true)) // xform))
|
{
|
inside = true;
|
}
|
Children().release(i);
|
if (inside)
|
{
|
break;
|
}
|
}
|
|
return inside;
|
}
|
|
|
void draw(ClickInfo info, int level, boolean select)
|
{
|
drawSelf(info, level, select);
|
}
|
|
Object3D GetRoot()
|
{
|
if (parent == null)
|
return this;
|
|
return parent.GetRoot();
|
}
|
|
Object3D GetFileRoot()
|
{
|
if (overflow)
|
return null;
|
|
overflow = true;
|
|
Object3D pfr = null;
|
|
if (parent == null && fileparent == null)
|
pfr = this;
|
|
if (parent == null && fileparent != null) // V4.gfd???
|
pfr = fileparent;
|
|
if (pfr == null && parent == null)
|
pfr = this;
|
|
if (pfr == null)
|
pfr = parent.GetFileRoot();
|
|
overflow = false;
|
|
return pfr;
|
}
|
|
cTreePath GetPath()
|
{
|
if (parent == null || blockloop)
|
return new cTreePath(this);
|
|
blockloop = true;
|
cTreePath path = new cTreePath(parent.GetPath(), this);
|
blockloop = false;
|
|
return path;
|
}
|
|
Object3D GetObject(String[] tp, int index)
|
{
|
if (blockloop)
|
return null;
|
|
if (index >= tp.length)
|
return this;
|
else
|
{
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
|
if (child == null)
|
continue;
|
|
//release(i);
|
|
if (child.GetName().equals(tp[index]))
|
{
|
blockloop = true;
|
Object3D o = child.GetObject(tp, index+1);
|
blockloop = false;
|
return o;
|
}
|
}
|
return null;
|
}
|
}
|
|
cTreePath GetTreePath(String[] tp, int index)
|
{
|
if (blockloop)
|
return null;
|
|
if (index >= tp.length)
|
return new cTreePath(this);
|
else
|
{
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // july 2013 reserve(i);
|
|
if (child == null)
|
continue;
|
|
//release(i);
|
|
if (child.GetName().equals(tp[index]))
|
{
|
blockloop = true;
|
cTreePath ctp = new cTreePath(this, child.GetTreePath(tp, index+1));
|
blockloop = false;
|
|
return ctp;
|
}
|
}
|
return null;
|
}
|
}
|
|
cTreePath SelectLeaf(int indexcount, boolean deselect)
|
{
|
if (hide || dontselect)
|
return null;
|
|
if (count <= 0)
|
{
|
return null;
|
}
|
|
if (HasTransparency())
|
return null;
|
|
//assert parent != null;
|
|
//System.out.println("Select : " + this);
|
|
if (GetBRep() != null)
|
{
|
return CameraPane.Match(indexcount) ? new cTreePath(this) : null;
|
} else
|
{
|
return null;
|
}
|
}
|
|
ObjEditor GetWindow()
|
{
|
if (editWindow != null)
|
return editWindow;
|
|
return manipWindow;
|
}
|
|
cTreePath Select(int indexcount, boolean deselect)
|
{
|
if (hide || dontselect)
|
return null;
|
|
if (count <= 0)
|
{
|
return null;
|
}
|
|
if (GetBRep() != null)
|
{
|
cTreePath tp = SelectLeaf(indexcount, deselect);
|
|
// //HANDLE
|
// if (tp != null || !(this instanceof BezierPatch))
|
// return tp;
|
if (tp != null)
|
return tp;
|
}
|
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
|
if (child == null)
|
continue;
|
if (!child.HasTransparency())
|
{
|
cTreePath leaf = child.Select(indexcount, deselect);
|
|
release(i);
|
|
if (leaf != null)
|
{
|
cTreePath tp = new cTreePath(this, leaf);
|
ObjEditor window = GetWindow();
|
if (window != null)
|
{
|
//System.out.println("editWindow = " + editWindow + " vs " + this);
|
window.Select(tp, deselect, true);
|
}
|
|
return tp;
|
}
|
} else
|
{
|
release(i);
|
}
|
}
|
|
for (int i = 0; i < size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
|
if (child == null)
|
continue;
|
|
if (child.HasTransparency() && child.size() != 0)
|
{
|
cTreePath leaf = child.Select(indexcount, deselect);
|
|
release(i);
|
|
if (leaf != null)
|
{
|
cTreePath tp = new cTreePath(this, leaf);
|
ObjEditor window = GetWindow();
|
if (window != null)
|
{
|
window.Select(tp, deselect, true);
|
}
|
|
return tp;
|
}
|
} else
|
{
|
release(i);
|
}
|
}
|
|
return null;
|
}
|
|
/*transient*/ double[][] globalTransform = null; // new double[4][4];
|
|
double[][] GlobalTransform()
|
{
|
if (globalTransform == null)
|
{
|
globalTransform = new double[4][4];
|
}
|
|
if (fromParent != null && !(this instanceof Texture || this instanceof TextureNode))
|
{
|
LA.matIdentity(globalTransform);
|
for (int i=GetTransformCount(); --i>=0;)
|
LA.matConcat(globalTransform, fromParent, globalTransform);
|
// LA.matCopy(fromParent, globalTransform);
|
}
|
else
|
{
|
LA.matIdentity(globalTransform);
|
}
|
|
if (parent != null)
|
//??
|
//LA.matConcat(globalTransform, parent.GlobalTransform(), globalTransform);
|
{
|
LA.matConcat(parent.GlobalTransform(), globalTransform, globalTransform);
|
}
|
|
//System.out.println("Object = " + this + ";\n toParent = " + CameraPane.Matrix(toParent) + ";\n global = " + CameraPane.Matrix(globalTransform));
|
|
return globalTransform;
|
}
|
|
double[][] GlobalTransformInv()
|
{
|
if (globalTransform == null)
|
{
|
globalTransform = new double[4][4];
|
}
|
|
if (blockloop)
|
{
|
LA.matIdentity(globalTransform);
|
return globalTransform;
|
}
|
|
if (toParent != null && !(this instanceof Texture || this instanceof TextureNode))
|
{
|
LA.matIdentity(globalTransform);
|
for (int i=GetTransformCount(); --i>=0;)
|
LA.matConcat(globalTransform, toParent, globalTransform);
|
// LA.matCopy(toParent, globalTransform);
|
}
|
else
|
{
|
LA.matIdentity(globalTransform);
|
}
|
|
if (parent != null) // || fileparent != null) // && parent.attributes == 0)
|
//?? LA.matConcat(globalTransform, parent.GlobalTransform(), globalTransform);
|
{
|
blockloop = true;
|
LA.matConcat(globalTransform, (parent!=null?parent:fileparent).GlobalTransformInv(), globalTransform);
|
blockloop = false;
|
}
|
|
//System.out.println("Object = " + this + ";\n toParent = " + CameraPane.Matrix(toParent) + ";\n global = " + CameraPane.Matrix(globalTransform));
|
|
return globalTransform;
|
}
|
|
void PreprocessOcclusion(iCameraPane cp)
|
{
|
/*
|
if (AOdone)
|
return;
|
|
AOdone = true;
|
*/
|
if (blockloop)
|
return;
|
|
if (count <= 0 || this instanceof Light)
|
return;
|
|
if (bRep != null)
|
{
|
System.out.println("processing " + this + ": " + bRep.VertexCount() // getRawVertices().length / 3)
|
+ " vertices...");
|
bRep.PreprocessOcclusion(cp, GlobalTransformInv());
|
Touch();
|
}
|
|
int nb = size();
|
for (int i = 0; i < nb; i++)
|
{
|
// WARNING LOOP
|
Object3D child = (Object3D) Children().reserve(i);
|
//Object3D child = (Object3D) get(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.PreprocessOcclusion(cp);
|
blockloop = false;
|
|
Children().release(i);
|
}
|
}
|
|
void addChild(Object3D child)
|
{
|
//new Exception().printStackTrace();
|
/*children.*/addElement(child);
|
/**/
|
//System.out.println("Add " + child + " to " + this);
|
//System.out.println("iscontained? " + IsContainedIn(child));
|
/**/
|
if (child.parent == null || !IsContainedIn(child)) // criss de patch de fou...
|
{
|
child.setParent(this);
|
//System.out.println("Set parent = " + child.parent);
|
}
|
|
Touch();
|
}
|
|
// void removeChild(Object3D child)
|
// {
|
// }
|
void removeChild(Object3D child)
|
{
|
if (blockloop)
|
return;
|
|
/*
|
child.setParent(null);
|
Children().removeElement(child);
|
*/
|
//System.out.println("child = " + child);
|
//System.out.println("child.parent = " + child.parent);
|
//System.out.println("this = " + this);
|
|
if (Children().indexOf(child) >= 0)
|
{
|
child.setParent(null);
|
Children().removeElement(child);
|
} else
|
{
|
// removeChild(child.parent);
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D obj = (Object3D) Children().reserve(i);
|
if (obj == null)
|
continue;
|
blockloop = true;
|
obj.removeChild(child);
|
blockloop = false;
|
Children().release(i);
|
}
|
}
|
|
if (selection != null)
|
selection.removeElement(child);
|
|
Touch();
|
}
|
|
|
cTreePath GetTreePath()
|
{
|
if (parent == null || parent.IsContainedIn(this))
|
{
|
return new cTreePath(this);
|
}
|
|
return new cTreePath(parent.GetTreePath(), this);
|
}
|
|
void AppendSelectionTreePaths(Vector tps)
|
{
|
}
|
// transient int displaylist = 0; // -1;
|
transient boolean touched = true;
|
transient boolean softtouched = true;
|
|
void Touch()
|
{
|
memorysize = 0;
|
|
CameraPane.touched = true;
|
|
// should use blockloop instead...
|
viewCode = -1;
|
if (count <= 0)
|
{
|
return;
|
}
|
//System.out.println("Touch " + this); // new Exception().printStackTrace();
|
//new Exception().printStackTrace();
|
touched = true;
|
|
softtouched = true;
|
if (bRep != null)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0; // june 2013 -1;
|
}
|
|
if (parent != null)
|
{
|
count--;
|
parent.Touch();
|
count++;
|
} else //
|
if (editWindow != null)
|
{
|
//editWindow.cameraView.lighttouched = true;
|
Globals.lighttouched = true;
|
}
|
}
|
|
void SoftTouch()
|
{
|
//System.out.println("SoftTouch " + this); //new Exception().printStackTrace();
|
viewCode = -1;
|
softtouched = true;
|
CameraPane.touched = true;
|
//touched = true; // tempo
|
//if (parent != null)
|
// parent.Touch();
|
}
|
|
void HardTouch()
|
{
|
//System.out.println("HardTouch " + this); // new Exception().printStackTrace();
|
//new Exception().printStackTrace();
|
touched = true;
|
CameraPane.touched = true;
|
//if (parent != null)
|
// parent.Touch();
|
|
if (bRep != null) // jan 2014
|
bRep.vertextable = null;
|
}
|
|
transient
|
boolean metablock; // grrr
|
|
void ResetBlockLoop()
|
{
|
if (metablock)
|
return;
|
|
metablock = true;
|
|
blockloop = false;
|
|
for (int i = 0; i < Size(); i++)
|
{
|
Object3D child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.ResetBlockLoop();
|
// release(i);
|
}
|
|
metablock = false;
|
}
|
|
void ResetDisplayList()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
//System.out.println("Reset " + this); // new Exception().printStackTrace();
|
//new Exception().printStackTrace();
|
if (bRep != null)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0; // june 2013 -1;
|
}
|
|
touched = true;
|
CameraPane.touched = true;
|
|
// Patch...
|
if (parent != null)
|
{
|
if (selection == null)
|
selection = new Object3D();
|
selection.clear();
|
}
|
|
Object3D child;
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) get(i); // reserve(i);
|
if (child == null)
|
continue;
|
child.ResetDisplayList();
|
// release(i);
|
}
|
|
blockloop = false;
|
}
|
|
void ResetSelectable()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
keepdontselect = dontselect;
|
dontselect = true;
|
|
Object3D child;
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
child.ResetSelectable();
|
}
|
|
blockloop = false;
|
}
|
|
void RestoreSelectable()
|
{
|
if (blockloop)
|
return;
|
|
blockloop = true;
|
|
dontselect = keepdontselect;
|
|
Object3D child;
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) get(i);
|
if (child == null)
|
continue;
|
child.RestoreSelectable();
|
}
|
|
blockloop = false;
|
}
|
|
boolean IsSelected()
|
{
|
if (parent == null)
|
{
|
return false;
|
}
|
|
return true; // parent.IsSelected(this);
|
}
|
|
transient Object3D selection; // ??? = new Object3D(); // new selectees...
|
|
protected void finalize()
|
{
|
//System.out.println(this + " (id=" + list + ") HAS BEEN DESTROYED...");
|
//CameraPane.RemoveList(list);
|
}
|
|
String GetToolTip()
|
{
|
if (parent instanceof Mocap)
|
return parent.GetToolTip();
|
|
return name!=null?name:"NULL";
|
}
|
|
cTexture texture = null; // new cTexture("SERIAL");
|
cTexture textures = null; // new cTexture("SERIAL");
|
cTexture usedtextures = null; // new cTexture("SERIAL");
|
|
cTexture GetTextures()
|
{
|
if (usedtextures == null)
|
{
|
// convert "texture" and "textures"
|
if (texture == null && textures == null)
|
{
|
usedtextures = new cTexture(":");
|
}
|
else
|
{
|
if (texture == null)
|
{
|
usedtextures = textures;
|
}
|
else
|
{
|
usedtextures = texture;
|
}
|
}
|
}
|
|
return usedtextures;
|
}
|
|
static String GetPigment(cTexture fullname)
|
{
|
if (fullname == null)
|
return "";
|
|
if (fullname.pigment != null)
|
{
|
return fullname.pigment;
|
}
|
|
// System.out.println("Fullname = " + fullname);
|
|
// Does not work on Windows due to C:
|
// if (fullname.name.indexOf(":") == -1)
|
// return fullname.name;
|
//
|
// return fullname.name.substring(0,fullname.name.indexOf(":"));
|
|
String[] split = fullname.name.split(":");
|
|
if (split.length == 0)
|
{
|
return fullname.pigment = "";
|
}
|
|
if (split.length <= 2)
|
{
|
if (fullname.name.endsWith(":"))
|
{
|
// Windows
|
return fullname.pigment = fullname.name.substring(0, fullname.name.length()-1);
|
}
|
|
return fullname.pigment = split[0];
|
}
|
|
// Windows
|
assert(split.length == 4);
|
|
return fullname.pigment = split[0] + ":" + split[1];
|
}
|
|
static String GetBump(cTexture fullname)
|
{
|
if (fullname == null)
|
return "";
|
|
if (fullname.bump != null)
|
{
|
return fullname.bump;
|
}
|
|
// System.out.println("Fullname = " + fullname);
|
// Does not work on Windows due to C:
|
// if (fullname.name.indexOf(":") == -1)
|
// return "";
|
//
|
// return fullname.name.substring(fullname.name.indexOf(":")+1,fullname.name.length());
|
String[] split = fullname.name.split(":");
|
|
if (split.length == 0)
|
{
|
return fullname.bump = "";
|
}
|
|
if (split.length == 1)
|
{
|
return fullname.bump = "";
|
}
|
|
if (split.length == 2)
|
{
|
if (fullname.name.endsWith(":"))
|
{
|
// Windows
|
return fullname.bump = "";
|
}
|
|
return fullname.bump = split[1];
|
}
|
|
// Windows
|
assert(split.length == 4);
|
|
return fullname.bump = split[2] + ":" + split[3];
|
}
|
|
String GetPigmentTexture()
|
{
|
return GetPigment(GetTextures());
|
}
|
|
String GetBumpTexture()
|
{
|
return GetBump(GetTextures());
|
}
|
|
void SetPigmentTexture(String tex)
|
{
|
if (tex != null && tex.toLowerCase().endsWith("tr.jpg"))
|
{
|
System.out.println("Processing transparency map... " + tex);
|
|
try
|
{
|
BufferedImage tr = ImageIO.read(new java.io.File(tex));
|
String pig = tex.substring(0, tex.length()-7);
|
System.out.println("Processing pigment map... " + pig + ".jpg");
|
BufferedImage pigment = ImageIO.read(new java.io.File(pig + ".jpg"));
|
|
// assert(tr.getWidth() == pigment.getWidth());
|
// assert(tr.getHeight() == pigment.getHeight());
|
|
int minwidth = tr.getWidth();
|
int minheight = tr.getHeight();
|
|
if (minwidth > pigment.getWidth())
|
{
|
minwidth = pigment.getWidth();
|
}
|
if (minheight > pigment.getHeight())
|
{
|
minheight = pigment.getHeight();
|
}
|
|
BufferedImage rendImage = new BufferedImage(minwidth, minheight, BufferedImage.TYPE_INT_ARGB); // ImageIO.read(infile);
|
|
for (int i=0; i<minwidth; i++)
|
{
|
for (int j=0; j<minheight; j++)
|
{
|
int pix = pigment.getRGB(i * pigment.getWidth() / minwidth, j * pigment.getHeight() / minheight);
|
|
pix &= 0xFFFFFF;
|
|
int trpix = tr.getRGB(i * tr.getWidth() / minwidth, j * tr.getHeight() / minheight);
|
|
trpix <<= 24; // -> Alpha
|
|
rendImage.setRGB(i,j, pix | trpix);
|
}
|
}
|
//rendImage.setRGB(0,0,VPheight/16*16,VPwidth/2*2,pixels,VPheight*(VPwidth-1),-VPheight);
|
ImageIO.write(rendImage, "png", new java.io.File(pig + ".png"));
|
|
tex = pig + ".png";
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
}
|
|
System.out.print("Pigment = " + tex);
|
System.out.print("; texture = " + texture);
|
System.out.print("; textures = " + textures);
|
System.out.println("; usedtextures = " + usedtextures);
|
|
if (GetTextures() == null) // What is that??
|
GetTextures().name = ":";
|
|
String texname = tex;
|
|
if (tex == null)
|
texname = "";
|
|
GetTextures().name = texname + ":" + GetBump(GetTextures());
|
|
GetTextures().pigment = null;
|
|
Touch();
|
}
|
|
void ResetPigmentTexture()
|
{
|
if (blockloop)
|
return;
|
|
SetPigmentTexture(null);
|
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
Object3D child = (Object3D) get(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.ResetPigmentTexture();
|
blockloop = false;
|
}
|
}
|
|
UUID GetUUID()
|
{
|
if (uuid == null)
|
{
|
// Serial
|
uuid = UUID.randomUUID();
|
}
|
|
return uuid;
|
}
|
|
Object3D GetObject(UUID uid)
|
{
|
if (blockloop)
|
return null;
|
|
if (GetUUID().equals(uid))
|
return this;
|
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
Object3D child = (Object3D) get(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
Object3D obj = child.GetObject(uid);
|
blockloop = false;
|
if (obj != null)
|
return obj;
|
}
|
|
return null;
|
}
|
|
void SetBumpTexture(String tex)
|
{
|
if (GetTextures() == null)
|
GetTextures().name = ":";
|
|
String texname = tex;
|
|
if (tex == null)
|
texname = "";
|
|
GetTextures().name = Object3D.GetPigment(GetTextures()) + ":" + texname;
|
|
GetTextures().bump = null;
|
|
Touch();
|
}
|
|
void ResetBumpTexture()
|
{
|
if (blockloop)
|
return;
|
|
SetBumpTexture(null);
|
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
Object3D child = (Object3D) get(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.ResetBumpTexture();
|
blockloop = false;
|
}
|
}
|
|
void EmbedTextures(boolean embed)
|
{
|
if (blockloop)
|
return;
|
|
//if (GetTextures() != null)
|
if (embed)
|
CameraPane.EmbedTextures(GetTextures());
|
else
|
{
|
GetTextures().pigmentdata = null;
|
GetTextures().bumpdata = null;
|
GetTextures().pw = 0;
|
GetTextures().ph = 0;
|
GetTextures().bw = 0;
|
GetTextures().bh = 0;
|
}
|
|
int nb = Size();
|
for (int i = 0; i < nb; i++)
|
{
|
Object3D child = (Object3D) get(i);
|
|
if (child == null)
|
continue;
|
|
blockloop = true;
|
child.EmbedTextures(embed);
|
blockloop = false;
|
}
|
}
|
|
void draw(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
Draw(display, root, selected, blocked);
|
}
|
|
boolean NeedSupport()
|
{
|
return
|
CameraPane.SUPPORT && (!CameraPane.movingcamera || (!Globals.FREEZEONMOVE && Globals.isLIVE())) && link2master && /*live &&*/ support != null
|
// PROBLEM with CROWD!!
|
&& (Globals.DrawMode() == iCameraPane.SHADOW || !Globals.RENDERSHADOW || Globals.CROWD);
|
}
|
|
static boolean DEBUG_SELECTION = false;
|
|
boolean IsLive()
|
{
|
if (live)
|
return true;
|
|
if (parent == null)
|
return false;
|
|
return parent.IsLive();
|
}
|
|
boolean IsDynamic()
|
{
|
return live && bRep != null;
|
}
|
|
void Draw(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
Invariants(); // june 2013
|
|
if (support != null)
|
{
|
// System.err.println("Draw " + this + " Frame # " + ((Mocap)((Merge)support).object).frame);
|
}
|
|
if (display.DrawMode() == iCameraPane.SELECTION &&
|
(hide || dontselect))
|
return;
|
|
if (name != null && name.contains("sclera"))
|
name = name;
|
|
if (NeedSupport())
|
resetMasterNode(live);
|
|
// if (hide)
|
// return; // NEW!
|
|
if (name != null && name.contains("sclera"))
|
name = name;
|
|
if (this instanceof Checker)
|
return;
|
|
if (display.DrawMode() == display.SHADOW && PASSTEST)
|
return;
|
|
if (count <= 0)
|
{
|
return;
|
}
|
|
if ((//display.DrawMode() == CameraPane.SHADOW ||
|
display.DrawMode() == iCameraPane.SELECTION || display.IsDebugSelection()) && HasTransparency())
|
{
|
return;
|
}
|
|
//javax.media.opengl.GL gl = display.GetGL();
|
|
/*
|
if (touched)
|
{
|
if (list != -1)
|
{
|
System.out.println("del list " + list);
|
gl.glDeleteLists(list,1);
|
}
|
list = -1;
|
touched = false;
|
}
|
*/
|
|
if (support != null)
|
support = support;
|
|
boolean usecalllists = !IsDynamic() &&
|
IsStatic() && GetBRep() != null && (!CameraPane.SUPPORT || support == null || !link2master); // !(this instanceof cSpring) && !(this instanceof BezierPatch);
|
//boolean usecalllists = false; //!IsLive(); // IsStatic() && GetBRep() != null && (!CameraPane.SUPPORT || support == null) && !link2master; // !(this instanceof cSpring) && !(this instanceof BezierPatch);
|
|
//usecalllists &= display.DrawMode() == display.DEFAULT; // Don't compute list in shadow pass.
|
|
if (!usecalllists && bRep != null && bRep.displaylist > 0)
|
{
|
CameraPane.RemoveList(bRep.displaylist);
|
bRep.displaylist = 0;
|
}
|
// usecalllists &= !(parent instanceof RandomNode);
|
// usecalllists = false;
|
|
if (display.DrawMode() == display.SHADOW)
|
//GetBRep() != null)
|
usecalllists = !!usecalllists;
|
//System.out.println("draw " + this);
|
//new Exception().printStackTrace();
|
|
boolean compiled = false;
|
|
boolean selectmode = display.DrawMode() == display.SELECTION || display.IsDebugSelection();
|
|
if (!selectmode && //display.DrawMode() != display.SELECTION &&
|
//(touched || (bRep != null && bRep.displaylist <= 0)))
|
(Globals.isLIVE() && Globals.COMPUTESHADOWWHENLIVE || touched && Globals.COMPUTESHADOWWHENLIVE)) // || (bRep != null && bRep.displaylist <= 0)))
|
{
|
Globals.lighttouched = true;
|
} // all panes...
|
|
//if (usecalllists && display.DrawMode() != display.SELECTION && display.DrawMode() != display.SHADOW &&
|
if (bRep != null && usecalllists && !selectmode && // june 2013 display.DrawMode() != display.SHADOW &&
|
(touched || (bRep != null && bRep.displaylist <= 0)))
|
{
|
if (!(this instanceof Composite))
|
touched = false;
|
//if (displaylist == -1 && usecalllists)
|
if (bRep.displaylist <= 0 && usecalllists) // && display.DrawMode() == display.DEFAULT) // june 2013
|
{
|
bRep.displaylist = display.GenList();
|
assert(bRep.displaylist != 0);
|
// System.err.println("glGenLists: " + bRep.displaylist + " for " + this);
|
//System.out.println("\tgen list " + list);
|
// CameraPane.AddDuplicate(bRep.displaylist);
|
}
|
|
//System.out.println("\tnew list " + list);
|
//gl.glDrawBuffer(gl.GL_NONE);
|
if (usecalllists && bRep.displaylist > 0)
|
{
|
// System.err.println("new list " + bRep.displaylist + " for " + this);
|
display.NewList(bRep.displaylist);
|
}
|
|
CallList(display, root, selected, blocked);
|
|
// compiled = true;
|
if (usecalllists && bRep.displaylist > 0)
|
{
|
// System.err.println("end list " + bRep.displaylist + " for " + this);
|
display.EndList();
|
}
|
//gl.glDrawBuffer(gl.GL_BACK);
|
// XXX touched = false;
|
Globals.lighttouched = true; // all panes...
|
}
|
|
//touched = GetBRep() == null; // this instanceof Composite || this instanceof FileObject; // false;
|
touched = false;
|
|
if (this instanceof Texture || this instanceof TextureNode)
|
{
|
//System.out.println("Texture = " + toParent);
|
display.PushTextureMatrix(ToParent(), GetTransformCount());
|
} else
|
{
|
//System.out.println("Model = " + toParent);
|
// if (!(this instanceof cMesh) || !((cMesh)this).live)
|
// Invariants(); // june 2013
|
display.PushMatrix(ToParent(), GetTransformCount());
|
// else
|
// display.PushMatrix();
|
|
if (this instanceof Sphere)
|
{
|
// //assert(LA.isIdentity(toParent));
|
// LA.matIdentity(mat);
|
// cVector c = ((Sphere)this).center;
|
// LA.matTranslate(mat, c.x, c.y, c.z);
|
// //System.out.println("Center = " + c);
|
// display.MultMatrix(mat);
|
}
|
if (!cLinker.stack.empty()) // cLinker.stack.peek() != null)
|
{
|
cVector peek = cLinker.stack.peek();
|
LA.xformPos(peek, fromParent, peek);
|
}
|
}
|
|
boolean culled = false;
|
|
// frustum culling
|
if (CameraPane.FRUSTUM && !blocked && !IsInfinite() && GetBRep() != null // && GetBRep().VertexCount() != 1260 // default grid
|
&& display.DrawMode() != iCameraPane.SELECTION)
|
{
|
if (display.DrawMode() == iCameraPane.SHADOW)
|
{
|
if (!link2master // tricky to cull in shadow mode.
|
&& GetBRep().FrustumCull(this, null, display.LightCamera(), true))
|
{
|
//System.out.print("CULLED");
|
culled = true;
|
}
|
}
|
else
|
//GetBRep().getBounds(v0, v1, this);
|
if (GetBRep().FrustumCull(this, null, display.RenderCamera(), false))
|
culled = true;
|
|
// LA.xformPos(v0, display.renderCamera.toScreen, v0);
|
//
|
// System.out.print("v0 = " + v0);
|
//
|
// LA.xformPos(v1, display.renderCamera.toScreen, v1);
|
//
|
// System.out.println("; v1 = " + v1);
|
//
|
// double fov = display.renderCamera.shaper_fovy * Math.PI / 180;
|
//
|
// // average
|
// v2.set(v1);
|
// v2.add(v0);
|
// v2.mul(0.5);
|
//
|
// if (v2.z > 0)
|
// return; // behind
|
//
|
// double atan00x = Math.abs(Math.atan2(v2.x,-v2.z));
|
// double atan00y = Math.abs(Math.atan2(v2.y,-v2.z));
|
//
|
// System.out.print("FOV = " + fov);
|
// System.out.print("; X = " + atan00x);
|
// System.out.println("; Y = " + atan00y);
|
//
|
// if (atan00x > fov/4 ||
|
// atan00y > fov/4 ||
|
// false)
|
// return;
|
}
|
|
|
if (!culled)
|
if (display.DrawMode() == display.SELECTION || display.IsDebugSelection())
|
{
|
if (GetBRep() != null)
|
{
|
display.NextIndex();
|
|
// vertex color conflict : gl.glCallList(list);
|
DrawNode(display, root, selected);
|
if (this instanceof BezierPatch)
|
{
|
//drawSelf(display, root, selected);
|
}
|
}
|
//else
|
{
|
drawSelf(display, root, selected, blocked);
|
}
|
|
// if (!(this instanceof Composite))
|
// {
|
// for (int i = 0; i < size(); i++)
|
// {
|
// Object3D child = (Object3D) reserve(i);
|
// if (child == null)
|
// continue;
|
//
|
// child.draw(display, root, selected, blocked);
|
//
|
// release(i);
|
// }
|
// }
|
} else
|
{
|
/*
|
float[] color = { aColor.getRed() / 255.0f, aColor.getGreen() / 255.0f, aColor.getBlue() / 255.0f, 1 };
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_AMBIENT_AND_DIFFUSE, color, 0);
|
color[0] /= 2;
|
color[1] /= 2;
|
color[2] /= 2;
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_AMBIENT_AND_DIFFUSE, color, 0);
|
*/
|
display.PushMaterial(this, selected);
|
|
//System.out.println("call list " + list);
|
//System.out.println();
|
if (//selected)
|
root != null && root.selection != null && root.selection.indexOf(this) != -1)
|
{
|
display.DrawString(this); // GetToolTip());
|
}
|
|
cTexture tex = null;
|
|
if (//display.drawMode != display.SHADOW &&
|
!selectmode//display.drawMode != display.SELECTION
|
)
|
{
|
tex = GetTextures();
|
}
|
|
boolean failedPigment = false;
|
boolean failedBump = false;
|
|
CameraPane.lastObject = this;
|
try
|
{
|
display.BindPigmentTexture(tex, texres);
|
}
|
catch (Exception e)
|
{
|
// System.err.println("FAILED: " + this);
|
failedPigment = true;
|
}
|
|
try
|
{
|
display.BindBumpTexture(tex, texres);
|
}
|
catch (Exception e)
|
{
|
//System.err.println("FAILED: " + this);
|
failedBump = true;
|
}
|
|
if (!compiled)
|
{
|
if (bRep == null || (bRep != null && bRep.displaylist <= 0) || !IsStatic() /*???*/)
|
{
|
CallList(display, root, selected, blocked);
|
} else
|
{
|
if (!display.IsFrozen() || selected)
|
{
|
if (bRep == null)
|
bRep = null;
|
|
// System.err.println("glCallList: " + bRep.displaylist + " for " + this);
|
assert(bRep.displaylist != 0);
|
display.CallList(bRep.displaylist);
|
// june 2013 drawSelf(display, root, selected);
|
}
|
}
|
|
assert (!(this instanceof Composite));
|
{
|
// CRASH MOCAP!! for (int i = 0; i < size(); i++)
|
// {
|
// Object3D child = (Object3D) reserve(i);
|
// if (child == null)
|
// continue;
|
//
|
// child.draw(display, root, selected, blocked);
|
//
|
// release(i);
|
// }
|
}
|
}
|
|
if (!failedBump)
|
display.ReleaseBumpTexture(tex);
|
|
if (!failedPigment)
|
display.ReleasePigmentTexture(tex);
|
|
display.PopMaterial(this, selected);
|
}
|
|
if (this instanceof Texture || this instanceof TextureNode)
|
{
|
display.PopTextureMatrix(FromParent());
|
} else
|
{
|
/*
|
System.out.println("PUSH2");
|
LA.matPrint(fromParent);
|
LA.matInvert(toParent, display.tmpmat);
|
System.out.println("REAL2");
|
LA.matPrint(display.tmpmat);
|
System.out.println();
|
*/
|
|
if (this instanceof Sphere)
|
{
|
// LA.matIdentity(mat);
|
// cVector c = ((Sphere)this).center;
|
// LA.matTranslate(mat, -c.x, -c.y, -c.z);
|
// display.MultMatrix(mat);
|
}
|
|
// if (!(this instanceof cMesh) || !((cMesh)this).live)
|
display.PopMatrix(FromParent());
|
// else
|
// display.PopMatrix();
|
|
if (!cLinker.stack.empty()) // cLinker.stack.peek() != null)
|
{
|
LA.xformPos(cLinker.stack.peek(), toParent, cLinker.stack.peek());
|
}
|
}
|
|
softtouched = false;
|
//
|
// if (CameraPane.SUPPORT && link2master && /*live &&*/ support != null && display.drawMode != display.SHADOW)
|
// resetMasterNode();
|
}
|
|
void CallList(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
if (GetBRep() != null)
|
{
|
DrawNode(display, root, selected);
|
if (this instanceof BezierPatch)
|
{
|
//drawSelf(display, root, selected);
|
}
|
}
|
else
|
{
|
drawSelf(display, root, selected, blocked);
|
}
|
}
|
|
boolean doSelection0(ClickInfo info, Rectangle r, int level)
|
{
|
return doSelectionSelf(info, r, level);
|
}
|
|
boolean doSelectionSelf(ClickInfo info, Rectangle r, int level)
|
{
|
if (true) // bRep == null || level == 0)
|
{
|
return false;
|
}
|
int hc = info.bounds.x + info.bounds.width / 2;
|
int vc = info.bounds.y + info.bounds.height / 2;
|
//double mat[][] = new double[4][4];
|
double[][] toscreen = info.toScreen;
|
if (toscreen == null)
|
{
|
toscreen = info.camera.toScreen;
|
}
|
LA.matConcat(toParent, toscreen, mat);
|
Vertex vertices[] = bRep.transform(mat);
|
|
boolean perspective = info.camera.perspective;
|
//? height = info.bounds.height;
|
|
//System.out.println("focal? = " + info.camera.focalLength);
|
for (int i = 0; i < vertices.length; i++)
|
{
|
Vertex vert = vertices[i];
|
|
if (perspective)
|
{
|
vert./*pos.*/z /= height;
|
vert./*pos.*/x /= vert./*pos.*/z;
|
vert./*pos.*/y /= vert./*pos.*/z;
|
}
|
|
int x = hc + (int) vert./*pos.*/x;
|
int y = vc - (int) vert./*pos.*/y;
|
if (r.contains(x, y))
|
{
|
return true;
|
}
|
}
|
|
return false;
|
}
|
|
static double[][] mat = new double[4][4];
|
static int[] Xs = new int[3];
|
static int[] Ys = new int[3];
|
//static java.awt.Polygon triangle = new java.awt.Polygon(Xs, Ys, 3);
|
static cVector v0 = new cVector();
|
static cVector v1 = new cVector();
|
static cVector v2 = new cVector();
|
static cVector v3 = new cVector();
|
static cVector v4 = new cVector();
|
static cVector v5 = new cVector();
|
static cVector v6 = new cVector();
|
static cVector v7 = new cVector();
|
static cVector v8 = new cVector();
|
double[] model = null; // new double[16];
|
|
static boolean PASSTEST;
|
|
boolean flipV = false; // true;
|
int texres = 0; // 0 = low, 1 = normal, 2 = high res texture
|
|
void drawSelf(iCameraPane display, Object3D /*Composite*/ root, boolean selected, boolean blocked)
|
{
|
if (display.DrawMode() == iCameraPane.SELECTION && dontselect)
|
return;
|
|
if (hide)
|
return;
|
// shadow optimisation
|
// if (display.drawMode == CameraPane.SELECTION && hide)
|
// return;
|
//
|
// if (!marked)
|
// {
|
// if (hide)
|
// return;
|
// }
|
// else
|
// {
|
// if (display.drawMode == CameraPane.DEFAULT && !hide)
|
// return;
|
//
|
// if (display.drawMode == CameraPane.SHADOW && hide)
|
// return;
|
// }
|
|
|
//if (size() == 0)
|
{
|
DrawNode(display, root, selected);
|
//return;
|
}
|
// }
|
//
|
// void drawSelfOld(CameraPane display, Object3D /*Composite*/ root, boolean selected)
|
// {
|
if (count <= 0) // || display.IsFreezed())
|
{
|
return;
|
}
|
|
//if (depth == 0)
|
//return;
|
//Applet3D.tracein("draw", this);
|
/*
|
cTexture tex = null;
|
|
if (display.drawMode != display.SELECTION &&
|
display.drawMode != display.SHADOW) // transparency map?
|
{
|
tex = GetTextures();
|
}
|
|
//System.out.println("Object = " + this);
|
|
// if (
|
display.BindTextures(tex); // )
|
*/
|
|
// {
|
// // ??????????????????????????? Touch();
|
// }
|
|
display.PushMaterial2(this, selected);
|
|
Object3D child;
|
boolean sel;
|
int nb = size();
|
/*
|
for (int i=0; i<nb; i++, child.draw(display, selected || child.IsSelected())) // , level + 1, sel))
|
{
|
child = (Object3D) children.get(i);
|
//sel = select;
|
//if (level == 0 && IsSelected(child))
|
sel = true;
|
}
|
*/
|
//depth -= 1;
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) reserve(i);
|
if (child == null)
|
continue;
|
|
if (!child.HasTransparency())
|
{
|
sel = root != null && root.selection != null && root.selection.indexOf(child) != -1;
|
// GrafreeD.tracein("draw ", child);
|
boolean wasblocked = blockdraw;
|
blockdraw = true;
|
child.draw(display, root, selected || sel, wasblocked || blocked); // || child.IsSelected());
|
blockdraw = false;
|
// GrafreeD.traceout("draw ", child);
|
}
|
|
release(i);
|
}
|
/*
|
for (int i = 0; i < nb; i++)
|
{
|
child = (Object3D) children.reserve(i);
|
|
if (child.HasTransparency())
|
{
|
sel = root.selectees != null && root.selectees.indexOf(child) != -1;
|
//Applet3D.tracein("T draw", child);
|
child.draw(display, root, selected || sel); // || child.IsSelected());
|
//Applet3D.traceout("draw", child);
|
}
|
|
children.release(i);
|
}
|
*/
|
//depth += 1;
|
|
display.PopMaterial2(this);
|
/*
|
display.ReleaseTextures(tex);
|
*/
|
//Applet3D.traceout("draw", this);
|
}
|
|
boolean drawingstarted;
|
|
//static cVector min,max;
|
|
void DrawNode(iCameraPane display, Object3D /*Composite*/ root, boolean selected)
|
{
|
if (display.DrawMode() == display.SHADOW && projectedVertices != null && projectedVertices.length > 2 && projectedVertices[2].y >= 10000)
|
return; // no shadow for transparent objects
|
|
if (display.DrawMode() == iCameraPane.SELECTION && dontselect)
|
return;
|
|
if (hide)
|
return;
|
|
if (scriptnode != null)
|
{
|
scriptnode.DrawNode(display, root, selected);
|
}
|
|
// shadow optimisation
|
// if (display.drawMode == CameraPane.SELECTION && hide)
|
// return;
|
//
|
// if (!marked)
|
// {
|
// if (hide)
|
// return;
|
// }
|
// else
|
// {
|
// if (display.drawMode == CameraPane.DEFAULT && !hide)
|
// return;
|
//
|
// if (display.drawMode == CameraPane.SHADOW && hide)
|
// return;
|
// }
|
|
//if(count <= 0)
|
// return;
|
if (this instanceof BezierPatch)
|
{
|
//drawSelf(display, root, selected);
|
//return;
|
}
|
|
if (bRep == null)
|
{
|
//System.out.println("NULL boundary : " + this);
|
return;
|
}
|
|
//bRep.GenUV(1/material.diffuseness);
|
// bRep.lock = true;
|
|
//javax.media.opengl.GL gl = display.GetGL();
|
|
if (CameraPane.BOXMODE && !selected) // || CameraPane.movingcamera)
|
{
|
int fc = bRep.FaceCount();
|
int vc = bRep.VertexCount();
|
|
if (true) // fc > 100 || vc > 100)
|
{
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
bRep.getMinMax(min, max, 100);
|
|
display.DrawBox(min, max);
|
|
return;
|
}
|
}
|
|
drawingstarted = true;
|
|
/*
|
cTexture tex = null;
|
|
if (display.drawMode != display.SELECTION &&
|
display.drawMode != display.SHADOW)
|
{
|
tex = GetTextures();
|
}
|
|
// boolean bound = false;
|
|
// if (
|
display.BindTextures(tex); //)
|
*/
|
|
// {
|
// bound = true;
|
//// ?>???????????????????????? Touch();
|
// }
|
//else
|
// System.out.println("Object = " + this);
|
|
boolean select = true; // false;
|
|
// PATCH to clear verticesCopy
|
if (bRep.trimmed)
|
{
|
bRep.getRawVertices();
|
}
|
|
//try
|
//{
|
if (bRep.stripified)
|
{
|
//throw new Error();
|
|
boolean selectmode = display.DrawMode() == display.SELECTION || display.IsDebugSelection();
|
|
int[] strips = bRep.getRawIndices();
|
|
if (strips == null)
|
{
|
// dec 2012
|
new Exception().printStackTrace();
|
return;
|
}
|
|
if (dontselect)
|
{
|
//bRep.GenerateNormalsMINE();
|
}
|
|
display.DrawGeometry(bRep, flipV, selectmode);
|
} else // catch (Error e)
|
{
|
// TRIANGLE ARRAY
|
if (IsOpaque()) // Static())
|
{
|
display.StartTriangles();
|
int facecount = bRep.FaceCount();
|
for (int i = 0; i < facecount; i++)
|
{
|
// System.out.print("list = ");
|
// for (int k = 0; k < facecount; k++)
|
// {
|
// Face face = bRep.GetFace(k);
|
// System.out.print("[" + face.p + ", " + face.q + ", " + face.r + "] ");
|
// }
|
// System.out.println();
|
|
int index = 16; // bRep.VertexCount()/2;
|
|
if (bRep.FaceCount() != facecount)
|
index = 16;
|
|
Face face = bRep.GetFace(i);
|
|
if (bRep.FaceCount() != facecount)
|
index = 16;
|
|
// if (face.p == index || face.q == index || face.r == index)
|
// continue;
|
|
// random
|
if (false) // ???? !IsStatic() && i<facecount-1)
|
{
|
int randomi = (int)(Math.random()*(facecount-i)) + i;
|
|
Face facerand = bRep.GetFace(randomi);
|
int k = face.p; face.p = facerand.p; facerand.p = k;
|
k = face.q; face.q = facerand.q; facerand.q = k;
|
k = face.r; face.r = facerand.r; facerand.r = k;
|
// System.out.println("randomi = " + randomi);
|
// System.out.print(" swap = ");
|
// for (k = 0; k < facecount; k++)
|
// {
|
// Face face2 = bRep.GetFace(k);
|
// System.out.print("[" + face2.p + ", " + face2.q + ", " + face2.r + "] ");
|
// }
|
// System.out.println();
|
|
}
|
|
// System.out.println("face = " + face.p + ", " + face.q + ", " + face.r);
|
Vertex p = bRep.GetVertex(face.p);
|
Vertex q = bRep.GetVertex(face.q);
|
Vertex r = bRep.GetVertex(face.r);
|
|
// v1.set(q);
|
// v1.sub(p);
|
// v2.set(r);
|
// v2.sub(p);
|
//
|
// v3.cross(v1, v2); // triangle normal
|
// v3.normalize();
|
//
|
// // if (p.norm.dot(v3) > -0.5 &&
|
// // q.norm.dot(v3) > -0.5 &&
|
// // r.norm.dot(v3) > -0.5)
|
// // continue;
|
|
display.DrawFace(this, p, q, r, face);
|
}
|
display.EndTriangles();
|
}
|
else
|
{
|
// SORT
|
int facecount = bRep.FaceCount();
|
|
if (facescompare == null || facescompare.length != facecount)
|
{
|
facescompare = new FaceCompare[facecount];
|
|
for (int k=0; k<facecount; k++)
|
{
|
facescompare[k] = new FaceCompare(k);
|
}
|
|
center = new cVector();
|
}
|
else
|
{
|
for (int k=0; k<facecount; k++)
|
{
|
facescompare[k].distance = -1;
|
}
|
}
|
|
//System.out.println("SORT");
|
|
java.util.Arrays.sort(facescompare);
|
|
display.StartTriangles();
|
for (int i = 0; i < facecount; i++)
|
{
|
Face face = bRep.GetFace(facescompare[i].index);
|
|
// if (face.p == 0 || face.q == 0 || face.r == 0)
|
// continue;
|
|
Vertex p = bRep.GetVertex(face.p);
|
Vertex q = bRep.GetVertex(face.q);
|
Vertex r = bRep.GetVertex(face.r);
|
|
display.DrawFace(this, p, q, r, face);
|
}
|
display.EndTriangles();
|
}
|
|
if (false) // live && support != null && support.bRep != null) // debug weights
|
{
|
/*
|
gl.glDisable(gl.GL_LIGHTING);
|
float[] colorV = new float[3];
|
|
cVector tmp = new cVector();
|
|
//for (int object = 1; object < support.bRep.startvertices.length; object++)
|
//for (int i = support.bRep.startvertices[object-1]; i < support.bRep.startvertices[object]; i++)
|
for (int i = 0; i < bRep.VertexCount()
|
; i++)
|
{
|
Vertex p = bRep.GetVertex(i);
|
|
if (p.vertexlinks == null)
|
continue;
|
|
// CameraPane.selectedpoint.
|
// getAverage(cStatic.point1, true);
|
cStatic.point1.set(0,0,0);
|
LA.xformPos(cStatic.point1, CameraPane.selectedpoint.toParent, cStatic.point1);
|
|
cStatic.point1.sub(p);
|
|
if (cStatic.point1.dot(cStatic.point1) > 0.00001)
|
continue;
|
|
// assert(p.weights[0] >= p.weights[1]);
|
|
for (int object = 0; object < p.vertexlinks.length; object++)
|
{
|
if (p.weights[object] == 0) // /p.totalweight < 0.01)
|
{
|
//assert(p.weights[object] == 0);
|
continue;
|
}
|
|
if (p.vertexlinks[object] == -1)
|
continue;
|
|
Vertex q = support.bRep.GetVertex(p.vertexlinks[object]);
|
cVector n = q.norm;
|
|
int color = object+1;
|
colorV[2] = color&1;
|
colorV[1] = (color&2)>>1;
|
colorV[0] = (color&4)>>2;
|
|
colorV[0] *= p.weights[object]/p.totalweight;
|
colorV[1] *= p.weights[object]/p.totalweight;
|
colorV[2] *= p.weights[object]/p.totalweight;
|
|
gl.glColor3f(colorV[0], colorV[1], colorV[2]);
|
gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE, colorV, 0);
|
gl.glMaterialfv(gl.GL_BACK, gl.GL_DIFFUSE, colorV, 0);
|
|
// gl.glColor3f(1, 1, 0);
|
gl.glBegin(gl.GL_LINES);
|
gl.glVertex3d(p.x, p.y, p.z);
|
gl.glVertex3d(q.x, q.y, q.z);
|
gl.glEnd();
|
|
Vertex s = support.bRep.GetVertex(p.vertexlinks2[object]);
|
|
gl.glColor3f(1, 1, 1);
|
gl.glBegin(gl.GL_LINES);
|
gl.glVertex3d(s.x, s.y, s.z);
|
gl.glVertex3d(q.x, q.y, q.z);
|
gl.glEnd();
|
|
// gl.glColor3f(1, 0, 1);
|
// gl.glBegin(gl.GL_LINES);
|
// gl.glVertex3d(q.x, q.y, q.z);
|
// tmp.set(n);
|
// tmp.mul(0.005);
|
// tmp.add(q);
|
// gl.glVertex3d(tmp.x, tmp.y, tmp.z);
|
// gl.glEnd();
|
}
|
}
|
*/
|
}
|
}
|
|
// bRep.lock = false;
|
/*
|
// if (bound)
|
display.ReleaseTextures(tex);
|
*/
|
}
|
|
transient cVector center;
|
|
class FaceCompare implements Comparable
|
{
|
int index;
|
double distance = -1;
|
|
FaceCompare(int k)
|
{
|
index = k;
|
}
|
|
public int compareTo(Object o)
|
{
|
FaceCompare facecomp = (FaceCompare) o;
|
|
return (DistanceToCamera() < facecomp.DistanceToCamera()) ? 1 : -1;
|
}
|
|
double DistanceToCamera()
|
{
|
if (distance == -1)
|
{
|
Face face = bRep.GetFace(index);
|
|
Vertex p = bRep.GetVertex(face.p);
|
Vertex q = bRep.GetVertex(face.q);
|
Vertex r = bRep.GetVertex(face.r);
|
|
center.set(p);
|
center.add(q);
|
center.add(r);
|
center.mul(1.0/3);
|
|
center.sub(Globals.theRenderer.EyeCamera().location);
|
|
distance = center.dot(center);
|
}
|
|
return distance;
|
}
|
}
|
|
transient FaceCompare[] facescompare = null;
|
|
void Print(Vertex v)
|
{
|
//System.err.println("(" + v.x + ", " + v.y + ", " + v.z + ")");
|
}
|
|
void drawSelf(ClickInfo info, int level, boolean select)
|
{
|
if (bRep == null)
|
{
|
System.out.println("NULL boundary 2 : " + this);
|
return;
|
}
|
|
int hc = info.bounds.x + info.bounds.width / 2;
|
int vc = info.bounds.y + info.bounds.height / 2;
|
//double mat[][];
|
double[][] toscreen = info.toScreen;
|
if (toscreen == null)
|
{
|
toscreen = info.camera.toScreen;
|
}
|
|
if (level == 0)
|
{
|
//mat = info.toScreen;
|
LA.matCopy(toscreen, mat);
|
} else
|
{
|
//mat = new double[4][4];
|
LA.matConcat(toParent, toscreen, mat);
|
}
|
|
Vertex vertices[] = bRep.transform(mat);
|
|
boolean perspective = info.camera.perspective;
|
assert (false);
|
height = info.bounds.height;
|
v0.set(info.camera.location);
|
LA.vecSub(v0, info.camera.lookAt, v1);
|
// SERIAL PATCH depth = (double) v1.length();
|
//System.out.println("depth = " + depth);
|
|
projectVertices(vertices, hc, vc, perspective);
|
|
/*
|
if (perspective)
|
{
|
for (int i=0; i<vertices.length; i++)
|
{
|
clipAndProject(height, vertices[i]);
|
}
|
}
|
*/
|
|
//if (select) info.g.setColor(aColorSelect);
|
//else info.g.setColor(aColor);
|
|
if (info.camera.focalLength != 1)
|
{
|
for (int i = 0; i < vertices.length; i++)
|
{
|
Vertex vert = vertices[i];
|
vert./*pos.*/x *= info.camera.focalLength; // * height;
|
vert./*pos.*/y *= info.camera.focalLength; // * height;
|
}
|
}
|
|
if (select)
|
{
|
fillColor = aColorSelect;
|
lineColor = aLineColorSelect;
|
} else
|
{
|
fillColor = aColor;
|
lineColor = aLineColor;
|
}
|
|
for (int i = 0; i < bRep.FaceCount(); i++)
|
{
|
Face face = bRep.GetFace(i);
|
// backfacing culling
|
//if (face.norm == null || face.norm.z > 0)
|
{
|
Vertex pv = vertices[face.p];
|
Vertex qv = vertices[face.q];
|
Vertex rv = vertices[face.r];
|
|
LA.vecSub(pv/*.pos*/, qv/*.pos*/, v0);
|
LA.vecSub(pv/*.pos*/, rv/*.pos*/, v1);
|
LA.vecCross(v0, v1, v2);
|
|
if (perspective)
|
{
|
double dot = LA.vecDot(v2, pv/*.pos*/);
|
|
face.dot = (int/*float*/) (dot / LA.vecLen(v2) / LA.vecLen(pv/*.pos*/));
|
} else
|
{
|
face.dot = (int/*float*/) (v2.z / LA.vecLen(v2));
|
}
|
}
|
}
|
|
for (int pass = 0; pass <= 1; pass++)
|
{
|
for (int i = 0; i < bRep.FaceCount(); i++)
|
{
|
Face face = bRep.GetFace(i);
|
// backfacing culling
|
//if (face.norm == null || face.norm.z > 0)
|
{
|
//Vertex pv = vertices[face.p];
|
//Vertex qv = vertices[face.q];
|
//Vertex rv = vertices[face.r];
|
|
//LA.vecSub(pv/*.pos*/,qv/*.pos*/, v0);
|
//LA.vecSub(pv/*.pos*/,rv/*.pos*/, v1);
|
//LA.vecCross(v0,v1, v2);
|
|
//double dot = LA.vecDot(v2, pv/*.pos*/);
|
|
double dot = face.dot;
|
|
//if ((dot > 0) ^ (pass == 0))
|
if ((dot > 0) ^ (pass == 0))
|
{
|
Vertex pv = vertices[face.p];
|
Vertex qv = vertices[face.q];
|
Vertex rv = vertices[face.r];
|
|
//LA.vecNormalize(v2);
|
//LA.vecCopy(pv/*.pos*/, v0);
|
//LA.vecNormalize(v0);
|
|
//int j = (int) (LA.vecDot(v2, v0) * colorTable.length);
|
int j;
|
|
//if (!perspective)
|
j = (int) (dot * // / LA.vecLen(v2) / LA.vecLen(pv/*.pos*/) *
|
100); // colorTable.length);
|
//else
|
// j = (int) (v2.z * // / LA.vecLen(v2) *
|
// colorTable.length);
|
|
//if ((j > 0) ^ (pass == 0))
|
{
|
if (j > 0)
|
{
|
if (select)
|
{
|
mode = EDGE;
|
} // |POINT;
|
else
|
{
|
mode = FACE;
|
}
|
//pv.touched = true;
|
//qv.touched = true;
|
//rv.touched = true;
|
} else
|
{
|
if (select)
|
{
|
mode = 0;
|
} // FACE; // |POINT;
|
else
|
{
|
mode = EDGE;
|
}
|
j = -j;
|
}
|
/*
|
if (j == colorTable.length)
|
{
|
j -= 1;
|
}
|
*/
|
fillColor = aColor; // tmpFillColor; //.set(aColor.getRed() * dot,
|
//aColor.getGreen() * dot,
|
//aColor.getBlue() * dot, 128); //colorTable[j];
|
drawFace(pv/*.pos*/, qv/*.pos*/, rv/*.pos*/,
|
face.p, face.q, face.r,
|
hc, vc,
|
info.g, perspective);
|
}
|
}
|
}
|
}
|
}
|
|
/*
|
if (false) // select)
|
{
|
info.g.setColor(lineColor);
|
for (int i=0; i < vertices.length; i++)
|
{
|
Vertex vert = vertices[i];
|
//if (perspective && LA.vecDot(vert.norm, vert) > 0 ||
|
//!perspective && vert.norm.z > 0)
|
if (vert.touched)
|
{
|
vert.touched = false;
|
int x; // = hc + (int)usep.x;
|
int y; // = vc - (int)usep.y;
|
//if (perspective)
|
//{
|
cVector2 usep;
|
usep = projectedVertices[i];
|
x = usep.x;
|
y = usep.y;
|
//vert.z /= height;
|
//vert.x /= vert.z;
|
//vert.y /= vert.z;
|
//}
|
//else
|
//{
|
//usep = vert;
|
//}
|
info.g.fillOval(x-3, y-3, 7, 7);
|
}
|
}
|
}
|
*/
|
}
|
|
void projectVertices(Vertex[] vertices, int hc, int vc, boolean perspective)
|
{
|
assert (false);
|
if (projectedVertices.length < vertices.length)
|
{
|
projectedVertices = new cVector2[vertices.length];
|
for (int i = 0; i < vertices.length; i++)
|
{
|
projectedVertices[i] = new cVector2();
|
}
|
}
|
|
for (int i = 0; i < vertices.length; i++)
|
{
|
if (perspective)
|
{
|
project(vertices, i, hc, vc);
|
} else
|
{
|
projectPara(vertices, i, hc, vc);
|
}
|
}
|
}
|
|
void project(Vertex[] v, int i, int hc, int vc)
|
{
|
cVector2 p = projectedVertices[i];
|
cVector q = v[i]/*.pos*/;
|
//p.z = q.z / height;
|
p.x = (int) (hc + height * q.x / q.z);
|
p.y = (int) (vc - height * q.y / q.z);
|
}
|
|
void projectPara(Vertex[] v, int i, int hc, int vc)
|
{
|
cVector2 p = projectedVertices[i];
|
cVector q = v[i]/*.pos*/;
|
p.x = (int) (hc + 200 * q.x); // /depth);
|
p.y = (int) (vc - 200 * q.y); // /depth);
|
}
|
|
void clipAndProject(cVector pv, cVector qv, cVector rv, int behind)
|
{
|
if (behind == 1)
|
{
|
if (qv.z < 1)
|
{
|
LA.vecCopy(qv, pp);
|
LA.vecCopy(rv, qq);
|
LA.vecCopy(pv, rr);
|
} else if (rv.z < 1)
|
{
|
LA.vecCopy(rv, pp);
|
LA.vecCopy(pv, qq);
|
LA.vecCopy(qv, rr);
|
}
|
double t = (1 - rr.z) / (pp.z - rr.z);
|
ss.x = rr.x + t * (pp.x - rr.x);
|
ss.y = rr.y + t * (pp.y - rr.y);
|
ss.z = 1;
|
t = (1 - qq.z) / (pp.z - qq.z);
|
pp.x = qq.x + t * (pp.x - qq.x);
|
pp.y = qq.y + t * (pp.y - qq.y);
|
pp.z = 1;
|
} else if (behind == 2)
|
{
|
if (qv.z >= 1)
|
{
|
LA.vecCopy(qv, pp);
|
LA.vecCopy(rv, qq);
|
LA.vecCopy(pv, rr);
|
} else if (rv.z >= 1)
|
{
|
LA.vecCopy(rv, pp);
|
LA.vecCopy(pv, qq);
|
LA.vecCopy(qv, rr);
|
}
|
double t = (1.0 - qq.z) / (pp.z - qq.z);
|
qq.x += t * (pp.x - qq.x);
|
qq.y += t * (pp.y - qq.y);
|
qq.z = 1;
|
t = (1.0 - rr.z) / (pp.z - rr.z);
|
rr.x += t * (pp.x - rr.x);
|
rr.y += t * (pp.y - rr.y);
|
rr.z = 1;
|
}
|
|
//pp.x *= height / pp.z;
|
pp.z /= height;
|
pp.x /= pp.z;
|
pp.y /= pp.z;
|
qq.z /= height;
|
qq.x /= qq.z;
|
qq.y /= qq.z;
|
rr.z /= height;
|
rr.x /= rr.z;
|
rr.y /= rr.z;
|
|
if (behind == 1)
|
{
|
ss.z /= height;
|
ss.x /= ss.z;
|
ss.y /= ss.z;
|
}
|
}
|
|
// not used...
|
void Toggle(int attr)
|
{
|
attributes ^= attr;
|
ClearList();
|
}
|
|
// transient cVector buffer;
|
|
double getFieldStrength(double x, double y, double z)
|
{
|
// if (buffer == null)
|
// buffer = new cVector();
|
|
// untransform(inpnt.x, inpnt.y, inpnt.z, buffer);
|
untransform(x, y, z, cStatic.point1);
|
x = cStatic.point1.x;
|
y = cStatic.point1.y;
|
z = cStatic.point1.z;
|
|
double total = 0;
|
|
int nb = size();
|
|
for (int i = 0; i < nb; i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
|
total += child.getFieldStrength(x,y,z);
|
|
release(i);
|
}
|
|
return total;
|
}
|
|
void drawFace(cVector pv, cVector qv, cVector rv,
|
int indexp, int indexq, int indexr,
|
int hc, int vc, Graphics g, boolean perspective)
|
{
|
int behind = 0;
|
|
cVector2 usep;
|
cVector2 useq;
|
cVector2 user;
|
cVector2 uses = null;
|
|
if (perspective)
|
{
|
if (pv.z < 1)
|
{
|
behind++;
|
}
|
if (qv.z < 1)
|
{
|
behind++;
|
}
|
if (rv.z < 1)
|
{
|
behind++;
|
}
|
|
if (behind == 3)
|
{
|
return;
|
}
|
|
if (behind != 0)
|
{
|
//LA.vecCopy(pv, pp);
|
//LA.vecCopy(qv, qq);
|
//LA.vecCopy(rv, rr);
|
|
clipAndProject(pv, qv, rv, behind);
|
|
pp2.x = (int) (hc + pp.x);
|
pp2.y = (int) (vc - pp.y);
|
qq2.x = (int) (hc + qq.x);
|
qq2.y = (int) (vc - qq.y);
|
rr2.x = (int) (hc + rr.x);
|
rr2.y = (int) (vc - rr.y);
|
|
if (behind == 1)
|
{
|
ss2.x = (int) (hc + ss.x);
|
ss2.y = (int) (vc - ss.y);
|
}
|
|
usep = pp2;
|
useq = qq2;
|
user = rr2;
|
uses = ss2;
|
} else
|
{
|
usep = projectedVertices[indexp];
|
useq = projectedVertices[indexq];
|
user = projectedVertices[indexr];
|
}
|
} else
|
{
|
usep = projectedVertices[indexp];
|
useq = projectedVertices[indexq];
|
user = projectedVertices[indexr];
|
//usep = pv;
|
//useq = qv;
|
//user = rv;
|
}
|
|
if (!perspective || behind == 0)
|
{
|
//g.drawLine(hc + (short)(int)pp.x, vc - (short)(int)pp.y, hc + (short)(int)qq.x, vc - (short)(int)qq.y);
|
//g.drawLine(hc + (short)(int)qq.x, vc - (short)(int)qq.y, hc + (short)(int)rr.x, vc - (short)(int)rr.y);
|
//g.drawLine(hc + (short)(int)rr.x, vc - (short)(int)rr.y, hc + (short)(int)pp.x, vc - (short)(int)pp.y);
|
int Xs0 = Xs[0] = /*hc + (short)(int)*/ usep.x;
|
int Ys0 = Ys[0] = /*vc - (short)(int)*/ usep.y;
|
int Xs1 = Xs[1] = /*hc + (short)(int)*/ useq.x;
|
int Ys1 = Ys[1] = /*vc - (short)(int)*/ useq.y;
|
int Xs2 = Xs[2] = /*hc + (short)(int)*/ user.x;
|
int Ys2 = Ys[2] = /*vc - (short)(int)*/ user.y;
|
if ((mode & FACE) != 0)
|
{
|
g.setColor(fillColor);
|
g.fillPolygon(Xs, Ys, 3); // triangle);
|
}
|
if ((mode & EDGE) != 0)
|
{
|
g.setColor(lineColor);
|
g.drawPolygon(Xs, Ys, 3); // triangle);
|
}
|
/*
|
CameraPane.allXs[CameraPane.allCount] = Xs[0];
|
CameraPane.allYs[CameraPane.allCount++] = Ys[0];
|
CameraPane.allXs[CameraPane.allCount] = Xs[1];
|
CameraPane.allYs[CameraPane.allCount++] = Ys[1];
|
CameraPane.allXs[CameraPane.allCount] = Xs[2];
|
CameraPane.allYs[CameraPane.allCount++] = Ys[2];
|
*/
|
if (CameraPane.Xmin > Xs0)
|
{
|
CameraPane.Xmin = Xs0;
|
}
|
if (CameraPane.Xmin > Xs1)
|
{
|
CameraPane.Xmin = Xs1;
|
}
|
if (CameraPane.Xmin > Xs2)
|
{
|
CameraPane.Xmin = Xs2;
|
}
|
if (CameraPane.Xmax < Xs0)
|
{
|
CameraPane.Xmax = Xs0;
|
}
|
if (CameraPane.Xmax < Xs1)
|
{
|
CameraPane.Xmax = Xs1;
|
}
|
if (CameraPane.Xmax < Xs2)
|
{
|
CameraPane.Xmax = Xs2;
|
}
|
if (CameraPane.Ymin > Ys0)
|
{
|
CameraPane.Ymin = Ys0;
|
}
|
if (CameraPane.Ymin > Ys1)
|
{
|
CameraPane.Ymin = Ys1;
|
}
|
if (CameraPane.Ymin > Ys2)
|
{
|
CameraPane.Ymin = Ys2;
|
}
|
if (CameraPane.Ymax < Ys0)
|
{
|
CameraPane.Ymax = Ys0;
|
}
|
if (CameraPane.Ymax < Ys1)
|
{
|
CameraPane.Ymax = Ys1;
|
}
|
if (CameraPane.Ymax < Ys2)
|
{
|
CameraPane.Ymax = Ys2;
|
}
|
} else if (behind == 1)
|
{
|
g.drawLine(/*hc +*/(short) (int) usep.x, /*vc -*/ (short) (int) usep.y, /*hc +*/ (short) (int) useq.x, /*vc -*/ (short) (int) useq.y);
|
g.drawLine(/*hc +*/(short) (int) useq.x, /*vc -*/ (short) (int) useq.y, /*hc +*/ (short) (int) user.x, /*vc -*/ (short) (int) user.y);
|
g.drawLine(/*hc +*/(short) (int) user.x, /*vc -*/ (short) (int) user.y, /*hc +*/ (short) (int) uses.x, /*vc -*/ (short) (int) uses.y);
|
} else
|
{
|
g.drawLine(/*hc +*/(short) (int) user.x, /*vc -*/ (short) (int) user.y, /*hc +*/ (short) (int) usep.x, /*vc -*/ (short) (int) usep.y);
|
g.drawLine(/*hc +*/(short) (int) usep.x, /*vc -*/ (short) (int) usep.y, /*hc +*/ (short) (int) useq.x, /*vc -*/ (short) (int) useq.y);
|
}
|
}
|
|
static ClickInfo clickInfo = new ClickInfo();
|
|
protected void calcHotSpot(cVector in, //ClickInfo clickInfo,
|
Point outPt, Rectangle outRec)
|
{
|
int hc = clickInfo.bounds.x + clickInfo.bounds.width / 2;
|
int vc = clickInfo.bounds.y + clickInfo.bounds.height / 2;
|
double[][] toscreen = clickInfo.toScreen;
|
if (toscreen == null)
|
{
|
toscreen = new Camera(clickInfo.camera.viewCode).toScreen;
|
}
|
cVector vec = in;
|
LA.xformPos(in, toscreen, in);
|
//System.out.println("Distance = " + info.camera.Distance());
|
vec.x *= 100 * clickInfo.camera.SCALE / clickInfo.camera.Distance();
|
vec.y *= 100 * clickInfo.camera.SCALE / clickInfo.camera.Distance();
|
outPt.x = hc + (int) vec.x;
|
outPt.y = vc - (int) vec.y;
|
outRec.x = outPt.x - 3;
|
outRec.y = outPt.y - 3;
|
outRec.width = outRec.height = 6;
|
}
|
|
protected Rectangle calcHotSpot(cVector in//, ClickInfo clickInfo
|
)
|
{
|
Point pt = new Point(0, 0);
|
Rectangle rec = new Rectangle();
|
calcHotSpot(in, //clickInfo,
|
pt, rec);
|
return rec;
|
}
|
|
void drawEditHandles0(//ClickInfo clickInfo,
|
int level)
|
{
|
if (level == 0)
|
{
|
return;
|
} else
|
{
|
cVector origin = new cVector();
|
//LA.xformPos(origin, toParent, origin);
|
if (this.clickInfo == null)
|
this.clickInfo = new ClickInfo();
|
|
Rectangle spot = calcHotSpot(origin); //, clickInfo);
|
Rectangle boundary = new Rectangle();
|
boundary.x = spot.x - 30;
|
boundary.y = spot.y - 30;
|
boundary.width = spot.width + 60;
|
boundary.height = spot.height + 60;
|
clickInfo.g.setColor(Color.white);
|
int spotw = spot.x + spot.width;
|
int spoth = spot.y + spot.height;
|
clickInfo.g.fillRect(spot.x, spot.y, spot.width, spot.height);
|
// if (CameraPane.Xmin > spot.x)
|
// {
|
// CameraPane.Xmin = spot.x;
|
// }
|
// if (CameraPane.Xmax < spotw)
|
// {
|
// CameraPane.Xmax = spotw;
|
// }
|
// if (CameraPane.Ymin > spot.y)
|
// {
|
// CameraPane.Ymin = spot.y;
|
// }
|
// if (CameraPane.Ymax < spoth)
|
// {
|
// CameraPane.Ymax = spoth;
|
// }
|
// if (CameraPane.Xmin > spot.x)
|
// {
|
// CameraPane.Xmin = spot.x;
|
// }
|
// if (CameraPane.Xmax < spotw)
|
// {
|
// CameraPane.Xmax = spotw;
|
// }
|
// if (CameraPane.Ymin > spot.y)
|
// {
|
// CameraPane.Ymin = spot.y;
|
// }
|
// if (CameraPane.Ymax < spoth)
|
// {
|
// CameraPane.Ymax = spoth;
|
// }
|
// bonhommes info.g.drawLine(spotw, spoth, spotw, spoth - boundary.height/2); // 15
|
//info.g.drawLine(spotw, spoth, spotw - boundary.width/2, spoth); // 15
|
spot.translate(32, 0);
|
clickInfo.g.setColor(Color.yellow);
|
clickInfo.g.fillRect(spot.x, spot.y, spot.width, spot.height);
|
|
spot.translate(32, 64);
|
spotw = spot.x + spot.width;
|
spoth = spot.y + spot.height;
|
clickInfo.g.setColor(Color.cyan);
|
clickInfo.g.fillRect(spot.x, spot.y, spot.width, spot.height);
|
// if (CameraPane.Xmin > spot.x)
|
// {
|
// CameraPane.Xmin = spot.x;
|
// }
|
// if (CameraPane.Xmax < spotw)
|
// {
|
// CameraPane.Xmax = spotw;
|
// }
|
// if (CameraPane.Ymin > spot.y)
|
// {
|
// CameraPane.Ymin = spot.y;
|
// }
|
// if (CameraPane.Ymax < spoth)
|
// {
|
// CameraPane.Ymax = spoth;
|
// }
|
clickInfo.g.setColor(Color.green);
|
clickInfo.g.drawArc(boundary.x + clickInfo.DX, boundary.y + clickInfo.DY,
|
(int)(boundary.width * clickInfo.W), (int)(boundary.height * clickInfo.W), 0, 360);
|
//info.g.drawArc(spot.x, spotw, spot.width/2, boundary.height/2, 0, 360);
|
// if (CameraPane.Xmin > boundary.x)
|
// {
|
// CameraPane.Xmin = boundary.x;
|
// }
|
// if (CameraPane.Xmax < boundary.x + boundary.width)
|
// {
|
// CameraPane.Xmax = boundary.x + boundary.width;
|
// }
|
// if (CameraPane.Ymin > boundary.y)
|
// {
|
// CameraPane.Ymin = boundary.y;
|
// }
|
// if (CameraPane.Ymax < boundary.y + boundary.height)
|
// {
|
// CameraPane.Ymax = boundary.y + boundary.height;
|
// }
|
return;
|
}
|
}
|
|
boolean doEditClick0(//ClickInfo clickInfo,
|
int level)
|
{
|
if (level == 0)
|
{
|
return false;
|
}
|
|
boolean retval = false;
|
|
startX = clickInfo.x;
|
startY = clickInfo.y;
|
|
hitSomething = -1;
|
cVector origin = new cVector();
|
//LA.xformPos(origin, toParent, origin);
|
Rectangle spot = new Rectangle();
|
if (centerPt == null)
|
{
|
centerPt = new Point(0, 0);
|
}
|
calcHotSpot(origin, //info,
|
centerPt, spot);
|
if (spot.contains(clickInfo.x, clickInfo.y))
|
{
|
hitSomething = hitCenter;
|
retval = true;
|
}
|
spot.translate(32, 0);
|
if (spot.contains(clickInfo.x, clickInfo.y))
|
{
|
hitSomething = hitRotate;
|
retval = true;
|
}
|
spot.translate(0, 32);
|
spot.translate(32, 0);
|
spot.translate(0, 32);
|
if (spot.contains(clickInfo.x, clickInfo.y))
|
{
|
hitSomething = hitScale;
|
|
double scale = 0.005f * clickInfo.camera.Distance();
|
double hScale = (double) (clickInfo.x - centerPt.x) / 64;
|
double sign = 1;
|
if (hScale < 0)
|
{
|
sign = -1;
|
}
|
hScale = sign*Math.pow(sign*hScale, scale * 50);
|
if (hScale < 0.01)
|
{
|
//hScale = 0.01;
|
}
|
|
double vScale = (double) (clickInfo.y - centerPt.y) / 64;
|
sign = 1;
|
if (vScale < 0)
|
{
|
sign = -1;
|
}
|
vScale = sign*Math.pow(sign*vScale, scale * 50);
|
if (vScale < 0.01)
|
{
|
//vScale = 0.01;
|
}
|
|
clickInfo.scale = Math.sqrt(hScale*hScale + vScale*vScale);
|
|
retval = true;
|
}
|
|
if (!retval)
|
{
|
return false;
|
}
|
|
//System.out.println("info.modifiers = " + info.modifiers);
|
modified = (clickInfo.modifiers & CameraPane.SHIFT) != 0; // Was META
|
//System.out.println("modified = " + modified);
|
//new Exception().printStackTrace();
|
//viewCode = info.pane.renderCamera.viewCode;
|
if (startMat == null)
|
{
|
startMat = new double[4][4];
|
}
|
|
if (toParent == null)
|
{
|
toParent = LA.newMatrix();
|
fromParent = LA.newMatrix();
|
}
|
|
boolean wasmarked = marked;
|
|
if (marked)
|
SwitchMark();
|
|
LA.matCopy(toParent, startMat);
|
|
if (wasmarked)
|
SwitchMark();
|
|
return true;
|
}
|
|
void doEditDrag0(//ClickInfo info,
|
boolean opposite)
|
{
|
if (hitSomething == 0)
|
{
|
return;
|
}
|
|
boolean wasmarked = marked;
|
|
if (marked)
|
SwitchMark();
|
|
//System.out.println("hitSomething = " + hitSomething);
|
|
double scale = 0.005f * clickInfo.camera.Distance();
|
|
cVector xlate = new cVector();
|
//cVector xlate2 = new cVector();
|
switch (hitSomething)
|
{
|
default:
|
assert (false);
|
break;
|
|
case hitCenter: // Translate
|
|
scale *= 0.05f * Globals.theRenderer.RenderCamera().Distance();
|
|
// Modified could snap
|
if (//modified ||
|
opposite)
|
{
|
//assert(false);
|
/*
|
double scale = (double)((info.x - startX) + 32) / 32;
|
if (scale < 0.01)
|
scale = 0.01;
|
if (scale > 100)
|
scale = 100;
|
LA.matCopy(startMat, toParent);
|
for (int i=0; i < 3; i++)
|
{
|
xlate.set(i, toParent[3][i]);
|
toParent[3][i] = 0;
|
}
|
LA.matScale(toParent, scale, scale, scale);
|
for (int i=0; i < 3; i++)
|
toParent[3][i] = xlate.get(i);
|
LA.matInvert(toParent, fromParent);
|
*/
|
cVector delta = LA.newVector(0, 0, startY - clickInfo.y);
|
LA.xformDir(delta, new Camera(clickInfo.camera.viewCode).fromScreen, delta);
|
|
LA.matCopy(startMat, toParent);
|
LA.matTranslate(toParent, delta.x * scale, delta.y * scale, delta.z * scale);
|
//LA.matHomogene(toParent, delta.x * scale, delta.y * scale, delta.z * scale);
|
LA.matInvert(toParent, fromParent);
|
} else
|
{
|
//LA.xformDir(delta, info.camera.fromScreen, delta);
|
cVector up = new cVector(clickInfo.camera.up);
|
cVector away = new cVector();
|
//cVector right2 = new cVector();
|
//LA.vecCross(up, cVector.Z, right);
|
//System.out.println("UP = " + up);
|
if (// ??? !CameraPane.LOCALTRANSFORM &&
|
parent != null) // ?
|
{
|
LA.matInvert(parent.GlobalTransform(), ClickInfo.matbuffer);
|
} else
|
{
|
System.out.println("PARENT WAS NULL");
|
LA.matIdentity(ClickInfo.matbuffer);
|
}
|
LA.xformDir(up, ClickInfo.matbuffer, up);
|
// if (!CameraPane.LOCALTRANSFORM)
|
LA.xformDir(up, Globals.theRenderer.RenderCamera().toScreen, up);
|
LA.xformDir(clickInfo.camera.away, ClickInfo.matbuffer, away);
|
// if (!CameraPane.LOCALTRANSFORM)
|
LA.xformDir(away, Globals.theRenderer.RenderCamera().toScreen, away);
|
//LA.vecCross(up, cVector.Z, right2);
|
|
cVector delta = LA.newVector(clickInfo.x - startX, startY - clickInfo.y, 0);
|
|
//System.out.println("DELTA0 = " + delta);
|
//System.out.println("AWAY = " + info.camera.away);
|
//System.out.println("UP = " + info.camera.up);
|
if (away.z > 0)
|
{
|
if (clickInfo.camera.up.x == 0) // LA.vecDot(right, right2)<0)
|
{
|
delta.x = -delta.x;
|
} else
|
{
|
delta.y = -delta.y;
|
}
|
}
|
|
double angle = Math.atan2(up.y, up.x) - Math.PI / 2; // - Math.atan2(info.camera.up.x, info.camera.up.y); // ??
|
LA.matIdentity(ClickInfo.matbuffer);
|
LA.matZRotate(ClickInfo.matbuffer, -angle);
|
//System.out.println("DELTA1 = " + delta);
|
LA.xformDir(delta, ClickInfo.matbuffer, delta);
|
//System.out.println("DELTA2 = " + delta);
|
LA.xformDir(delta, new Camera(clickInfo.camera.viewCode).fromScreen, delta);
|
LA.matCopy(startMat, toParent);
|
//System.out.println("DELTA3 = " + delta);
|
LA.matTranslate(toParent, delta.x * scale, delta.y * scale, delta.z * scale);
|
LA.matInvert(toParent, fromParent);
|
//LA.matPrint(toParent);
|
}
|
break;
|
|
case hitRotate: // rotate
|
int dx = clickInfo.x - centerPt.x;
|
int dy = -(clickInfo.y - centerPt.y);
|
double angle = (double) Math.atan2(dx, dy);
|
angle = -(1.570796 - angle);
|
|
//System.out.println("scale = " + scale);
|
angle *= scale * 50;
|
|
if (modified)
|
{
|
// Rotate 45 degrees
|
angle /= (Math.PI / 4);
|
angle = Math.floor(angle + 0.5);
|
angle *= (Math.PI / 4);
|
}
|
LA.matCopy(startMat, toParent);
|
/**/
|
for (int i = 0; i < 3; i++)
|
{
|
xlate.set(i, toParent[3][i]);
|
toParent[3][i] = 0;
|
}
|
/**/
|
|
switch (clickInfo.pane.RenderCamera().viewCode)
|
{
|
case 1: // '\001'
|
LA.matZRotate(toParent, angle);
|
break;
|
|
case 2: // '\002'
|
LA.matYRotate(toParent, -angle);
|
break;
|
|
case 3: // '\003'
|
LA.matXRotate(toParent, angle);
|
break;
|
default:
|
assert false;
|
}
|
/**/
|
for (int i = 0; i < 3; i++)
|
{
|
toParent[3][i] = xlate.get(i);
|
}
|
/**/
|
|
LA.matInvert(toParent, fromParent);
|
break;
|
|
case hitScale: // scale
|
double hScale = (double) (clickInfo.x - centerPt.x) / 64;
|
double sign = 1;
|
if (hScale < 0)
|
{
|
sign = -1;
|
}
|
hScale = sign*Math.pow(sign*hScale, scale * 50);
|
if (hScale < 0.01)
|
{
|
//hScale = 0.01;
|
}
|
|
double vScale = (double) (clickInfo.y - centerPt.y) / 64;
|
sign = 1;
|
if (vScale < 0)
|
{
|
sign = -1;
|
}
|
vScale = sign*Math.pow(sign*vScale, scale * 50);
|
if (vScale < 0.01)
|
{
|
//vScale = 0.01;
|
}
|
|
LA.matCopy(startMat, toParent);
|
/**/
|
for (int i = 0; i < 3; i++)
|
{
|
xlate.set(i, toParent[3][i]);
|
toParent[3][i] = 0;
|
}
|
/**/
|
|
double totalScale = Math.sqrt(hScale*hScale + vScale*vScale) / clickInfo.scale;
|
|
if (totalScale < 0.01)
|
{
|
totalScale = 0.01;
|
}
|
|
switch (clickInfo.pane.RenderCamera().viewCode)
|
{
|
case 3: // '\001'
|
if (modified || opposite)
|
{
|
if (modified) // && opposite)
|
LA.matScale(toParent, totalScale, totalScale, totalScale);
|
else
|
//LA.matScale(toParent, 1, hScale, vScale);
|
LA.matScale(toParent, totalScale, 1, 1);
|
} // vScale, 1);
|
else
|
{
|
// EXCEPTION!
|
LA.matScale(toParent, 1, totalScale, totalScale);
|
} // vScale, 1);
|
break;
|
|
case 2: // '\002'
|
if (modified || opposite)
|
{
|
if (modified) // && opposite)
|
LA.matScale(toParent, totalScale, totalScale, totalScale);
|
else
|
//LA.matScale(toParent, hScale, 1, vScale);
|
LA.matScale(toParent, 1, totalScale, 1);
|
} else
|
{
|
LA.matScale(toParent, totalScale, 1, totalScale);
|
}
|
break;
|
|
case 1: // '\003'
|
if (modified || opposite)
|
{
|
if (modified) // && opposite)
|
LA.matScale(toParent, totalScale, totalScale, totalScale);
|
else
|
//LA.matScale(toParent, hScale, vScale, 1);
|
LA.matScale(toParent, 1, 1, totalScale);
|
} else
|
{
|
LA.matScale(toParent, totalScale, totalScale, 1);
|
}
|
break;
|
}
|
/**/
|
for (int i = 0; i < 3; i++)
|
{
|
toParent[3][i] = xlate.get(i);
|
}
|
/**/
|
|
LA.matInvert(toParent, fromParent);
|
break;
|
}
|
|
if (wasmarked)
|
SwitchMark();
|
|
if (parent == null)
|
{
|
System.out.println("NULL PARENT");
|
//new Exception().printStackTrace();
|
} else
|
{
|
if (parent instanceof BezierPatch)
|
{
|
((BezierSurface)parent.parent).currentHandle = (Sphere)this;
|
// parent.parent.recalculate();
|
}
|
else
|
parent.Touch();
|
} // NEW ...
|
|
|
clickInfo.pane.repaint();
|
}
|
|
boolean overflow = false;
|
|
void TransformToWorld(cVector out) // , cVector out)
|
{
|
if (overflow)
|
return;
|
|
overflow = true;
|
|
// june 2013 ??? assert (in == out);
|
cVector in = out;
|
if (toParent != null && !(this instanceof Texture || this instanceof TextureNode))
|
{
|
for (int loop=GetTransformCount(); --loop>=0;)
|
{
|
LA.xformPos(in, toParent, out);
|
// june 2013 out.set(in);
|
// july 2013:
|
in.set(out);
|
}
|
}
|
if (parent != null || fileparent != null)
|
{
|
(parent!=null?parent:fileparent).TransformToWorld(out); //, out);
|
}
|
|
overflow = false;
|
}
|
|
void TransformToLocal(cVector out) //, cVector out)
|
{
|
// june 2013 ??? assert (in == out);
|
cVector in = out;
|
if (parent != null || fileparent != null)
|
{
|
(parent!=null?parent:fileparent).TransformToLocal(out); //, out);
|
}
|
|
if (!(this instanceof Texture || this instanceof TextureNode))
|
{
|
for (int loop=GetTransformCount(); --loop>=0;)
|
{
|
LA.xformPos(in, fromParent, out);
|
// june 2013 out.set(in);
|
// july 2013:
|
in.set(out);
|
}
|
}
|
}
|
|
// void invariants()
|
// {
|
// }
|
|
void invariants()
|
{
|
//GraphreeD.tracein(this);
|
for (int i = 0; i < Children().size(); i++)
|
{
|
Object3D child = (Object3D) Children().reserve(i);
|
if (child == null)
|
continue;
|
|
if (child.parent != null && child.parent != this)
|
{
|
System.err.println("INVARIANT FAIL: " + this);
|
child.parent = this;
|
}
|
child.invariants();
|
Children().release(i);
|
}
|
|
// assert selection != null;
|
//GraphreeD.traceout(this);
|
}
|
|
public boolean equals(Object o)
|
{
|
return this == o;
|
//return GetObject() == ((Object3D)o).GetObject();
|
}
|
|
static class cVector2 implements java.io.Serializable
|
{
|
int x;
|
int y;
|
}
|
|
public String toString()
|
{
|
//SizeOf.skipStaticField(true);
|
//SizeOf.turnOnDebug();
|
|
//return super.toString() + " (id=" + list + ")" + " (brep=" + bRep + ")";
|
//return name + " (id=" + list + ")" + " (brep=" + bRep + ") " + super.toString();
|
//return name + " (#tri = " + (bRep==null?0:bRep.VertexCount()) + ") " + super.toString();
|
|
String objname;
|
|
if (false) //parent != null)
|
{
|
objname = name + " " + System.identityHashCode(this) + " (" + parent.name + " " + System.identityHashCode(parent) + ")";
|
} else
|
{
|
objname = GetName() + (Math.abs(count) == 1000 ? (count == 1000 ? " " : " * ") : (" (" + (count - 1) + ")")) + /*(IsSelected()?"(selected) ":"") + (touched?"(touched) ":"") */ "";
|
} // + super.toString();
|
//return name + " (" + (SizeOf.deepSizeOf(this)/1024) + "K) " + this.getClass().getName();
|
|
if (!Globals.ADVANCED)
|
return objname;
|
|
return objname + " " + System.identityHashCode(this) + " " + GetUUID();
|
}
|
|
public int hashCode()
|
{
|
// Fuck Vector...
|
return System.identityHashCode(this);
|
}
|
|
static int tabcount = 0;
|
|
void PrintTabs()
|
{
|
for (int i=tabcount; --i>=0;)
|
System.out.print(" ");
|
}
|
|
public void SendInfo(String text, String style)
|
{
|
PrintTabs();
|
System.out.println(text);
|
}
|
|
void Dump(boolean full)
|
{
|
System.err.flush();
|
|
ObjEditor.AddInfo(this, this, full);
|
|
tabcount++;
|
for (int i=0; i<Size(); i++)
|
{
|
Object3D comp = (Object3D) reserve(i);
|
if (comp == null)
|
continue;
|
comp.Dump(full);
|
release(i);
|
}
|
tabcount--;
|
|
SendInfo(toString(), "");
|
}
|
|
static final int WIREFRAME = 1;
|
static final int FILL = 2;
|
static final int BACKFACE = 4;
|
|
int attributes = 0; // FILL;
|
|
void CloseUI()
|
{
|
if (objectUI != null)
|
{
|
objectUI.closeUI();
|
if (editWindow != null)
|
{
|
editWindow.ctrlPanel.FlushUI();
|
editWindow.refreshContents();
|
} // ? new
|
objectUI = null;
|
//???
|
if (parent != null)
|
{
|
editWindow = null;
|
} // ?
|
}
|
else
|
{
|
//editWindow.closeUI();
|
}
|
}
|
|
boolean root; // patch for edit windows
|
|
String name;
|
BoundaryRep bRep;
|
/*transient*/ double height; // patch for linker and simplex
|
/*transient*/ double depth; // used for linker distortion
|
/*transient*/ cVector2[] projectedVertices = new cVector2[0];
|
|
Object3D /*Composite*/ parent;
|
Object3D /*Composite*/ fileparent; // In the case of FileObject
|
|
double[][] toParent; // dynamic matrix
|
double[][] fromParent;
|
|
double[][] toParentMarked; // original matrix
|
double[][] fromParentMarked;
|
|
double[][] tempmatrix;
|
|
double[][] ToParent()
|
{
|
// if (marked)
|
// {
|
// if (toParentMarked == null)
|
// {
|
// toParentMarked = LA.newMatrix();
|
// LA.matCopy(toParent, toParentMarked);
|
// }
|
//
|
// return toParentMarked;
|
// }
|
// else
|
{
|
return toParent;
|
}
|
}
|
|
double[][] FromParent()
|
{
|
// if (fromParent == null)
|
// return null;
|
//
|
// if (marked)
|
// {
|
// if (fromParentMarked == null)
|
// {
|
// fromParentMarked = LA.newMatrix();
|
// LA.matCopy(fromParent, fromParentMarked);
|
// }
|
//
|
// return fromParentMarked;
|
// }
|
// else
|
{
|
return fromParent;
|
}
|
}
|
|
// void Assert(boolean b)
|
// {
|
// if (!b)
|
// {
|
// //assert(false);
|
// new Exception().printStackTrace();
|
// }
|
// }
|
|
|
void FullInvariants()
|
{
|
if (blockloop)
|
return;
|
|
//System.err.println("Invariants " + this);
|
|
blockloop = true;
|
|
Invariants();
|
|
for (int i=0; i<size(); i++)
|
{
|
get(i).FullInvariants();
|
}
|
|
blockloop = false;
|
}
|
|
void Invariants()
|
{
|
// if (name != null && name.contains("eyesocket"))
|
// {
|
// name = name;
|
// }
|
if (min == null) // ???
|
{
|
min = new cVector();
|
max = new cVector();
|
}
|
|
if (false) // Can crawl!!
|
{
|
Object3D sourcenode = GetFileRoot();
|
|
if (sourcenode != null && !sourcenode.name.contains("rclab"))
|
{
|
getBounds(min, max, true);
|
|
if (min.y != Double.POSITIVE_INFINITY && min.y > 2)
|
{
|
// sourcenode.getBounds(min, max, true);
|
sourcenode.getBounds(v0, v1, true);
|
// sourcenode.toParent = sourcenode.toParent;
|
// get(0).toParent = get(0).toParent;
|
// sourcenode.GlobalTransform();
|
}
|
}
|
}
|
|
//Dump(true);
|
|
if (support != null)
|
{
|
assert(bRep != null);
|
if (!(support instanceof GenericJoint)) // support.bRep != null)
|
Grafreed.Assert(support.bRep == bRep.support);
|
}
|
else
|
{
|
//assert(bRep == null || bRep.support == null);
|
if (bRep != null && bRep.support != null)
|
{
|
System.err.println("NOT A NULL SUPPORT FOR BREP: " + this);
|
bRep.support = null;
|
}
|
}
|
|
if (toParent == null)
|
return;
|
|
if (tempmatrix == null)
|
tempmatrix = new double[4][4];
|
|
LA.matConcat(fromParent, toParent, tempmatrix);
|
|
//Assert(LA.isIdentityEps(tempmatrix));
|
if (!LA.isIdentityEps(tempmatrix))
|
{
|
// TODO!!
|
System.err.println("CORRUPTED MATRIX!!! " + this);
|
// new Exception().printStackTrace();
|
LA.matInvert(toParent, fromParent);
|
}
|
}
|
|
transient ObjEditor editWindow;
|
transient ObjEditor manipWindow;
|
|
transient boolean pinned;
|
|
transient ObjectUI objectUI;
|
public static int povDepth = 0;
|
private static cVector tbMin = new cVector();
|
private static cVector tbMax = new cVector();
|
private static cVector tbIn = new cVector();
|
private static cVector tbOut = new cVector();
|
private static cVector pp = new cVector();
|
private static cVector qq = new cVector();
|
private static cVector rr = new cVector();
|
private static cVector ss = new cVector();
|
private static cVector2 pp2 = new cVector2();
|
private static cVector2 qq2 = new cVector2();
|
private static cVector2 rr2 = new cVector2();
|
private static cVector2 ss2 = new cVector2();
|
// private static cVector edge1 = new cVector();
|
// private static cVector edge2 = new cVector();
|
//private static cVector norm = new cVector();
|
/*transient private*/ int hitSomething;
|
static final int hitCenter = 1;
|
static final int hitScale = 2;
|
static final int hitRotate = 3;
|
/*transient*/ /*private*/ int viewCode; // Now used for transparency cache flag
|
/*transient*/ private Point centerPt;
|
/*transient*/ private int startX;
|
/*transient*/ private int startY;
|
/*transient*/ private boolean modified;
|
/*transient*/ private double startMat[][];
|
Color aColor, aColorSelect;
|
Color aLineColor, aLineColorSelect;
|
/*transient*/ Color fillColor, lineColor;
|
/*transient*/ int mode; // Now used for biparam
|
static final int FACE = 1;
|
static final int EDGE = 2;
|
static final int POINT = 4;
|
cMaterial material; // = new cMaterial();
|
|
cMaterial GetMaterial()
|
{
|
//System.out.println("this = " + this);
|
if (material != null || parent == null || parent.IsContainedIn(this))
|
{
|
return material;
|
} else
|
{
|
return parent.GetMaterial();
|
}
|
}
|
|
void SetAttributes(Object3D obj, int mask)
|
{
|
Object3D targ = this;
|
|
targ.NORMALPUSH = obj.NORMALPUSH;
|
|
if (obj.material != null)
|
{
|
if ((mask&MATERIAL)!=0) // ==(COLOR|MATERIAL))
|
{
|
if (targ.material == null)
|
// COPY targ.material = new cMaterial(tempsel.get(0).material);
|
targ.material = obj.material; // LINK
|
else
|
{
|
float tcolor = targ.material.color;
|
float tmodulation = targ.material.modulation;
|
|
targ.material.Set(obj.material);
|
|
if ((mask&COLOR)==0)
|
{
|
targ.material.color = tcolor;
|
targ.material.modulation = tmodulation;
|
}
|
|
if (targ.projectedVertices.length <= 2)
|
{
|
// Side effect...
|
Object3D.cVector2[] keep = targ.projectedVertices;
|
targ.projectedVertices = new Object3D.cVector2[3];
|
for (int i=0; i<3; i++)
|
{
|
if(i<keep.length)
|
targ.projectedVertices[i] = keep[i];
|
else
|
targ.projectedVertices[i] = new Object3D.cVector2();
|
}
|
}
|
|
if (obj.projectedVertices.length <= 2)
|
{
|
// Side effect...
|
Object3D.cVector2[] keep = obj.projectedVertices;
|
obj.projectedVertices = new Object3D.cVector2[3];
|
for (int i=0; i<3; i++)
|
{
|
if(i<keep.length)
|
obj.projectedVertices[i] = keep[i];
|
else
|
{
|
obj.projectedVertices[i] = new Object3D.cVector2();
|
if (i == 0)
|
obj.projectedVertices[i].x = 100; // criss de bug de bump
|
}
|
}
|
}
|
|
for (int i=obj.projectedVertices.length; --i>=0;)
|
{
|
targ.projectedVertices[i].x = obj.projectedVertices[i].x;
|
targ.projectedVertices[i].y = obj.projectedVertices[i].y;
|
}
|
}
|
}
|
else
|
if ((mask&COLOR)!=0) // COLOR)
|
{
|
//Object3D targ = group.selection.get(0);
|
if (targ.material != null)
|
{
|
targ.material.color = obj.material.color;
|
targ.material.modulation = obj.material.modulation;
|
}
|
}
|
// else
|
// if ((mask&MATERIAL)!=0) // MATERIAL)
|
// {
|
// //Object3D targ = group.selection.get(0);
|
// if (targ.material != null)
|
// {
|
// float tcolor = targ.material.color;
|
// float tmodulation = targ.material.modulation;
|
// targ.material.Set(obj.material);
|
// targ.material.color = tcolor;
|
// targ.material.modulation = tmodulation;
|
// }
|
// }
|
}
|
|
// if (obj.texture != null)
|
{
|
if ((mask&TEXTURE)!=0) // TEXTURE)
|
{
|
//group.selection.get(0)
|
targ.GetTextures().name = obj.GetTextures().name;
|
//group.selection.get(0)
|
targ.flipV = obj.flipV;
|
targ.texres = obj.texres;
|
targ.Touch();
|
}
|
}
|
}
|
|
boolean HasTransparency()
|
{
|
if (true) return false;
|
|
if (material == null || material.multiply)
|
{
|
return false;
|
}
|
|
//if (material.opacity != 1)
|
// System.out.println("HasTransparency = " + material.opacity);
|
return material.opacity < 0.99;
|
}
|
|
int count = 2; // 1 ??
|
|
void IncCount()
|
{
|
if (count == -1000)
|
{
|
count = 1000;
|
} else if (count != 1000)
|
{
|
count++;
|
}
|
}
|
|
void DecCount()
|
{
|
if (count == 1000)
|
{
|
count = -1000;
|
} else if (count > 1) // 0)
|
{
|
count--;
|
}
|
}
|
|
void IncDepth()
|
{
|
Object3D selectee;
|
for (int i = 0; i < selection.size(); i++)
|
{
|
selectee = (Object3D) selection.elementAt(i);
|
selectee.IncCount();
|
}
|
|
Touch();
|
}
|
|
void DecDepth()
|
{
|
Object3D selectee;
|
for (int i = 0; i < selection.size(); i++)
|
{
|
selectee = (Object3D) selection.elementAt(i);
|
selectee.DecCount();
|
}
|
|
Touch();
|
}
|
|
static Vertex s1 = new Vertex();
|
static Vertex s2 = new Vertex();
|
static Vertex s3 = new Vertex();
|
|
boolean intersectMesh(Ray ray, IntersectResult result)
|
{
|
boolean success = false;
|
|
if (bRep.stripified)
|
{
|
int[] strips = bRep.getRawIndices();
|
|
// TRIANGLE STRIP ARRAY
|
if (bRep.trimmed)
|
{
|
float[] v = bRep.getRawVertices();
|
|
int count3 = 0;
|
|
if (v.length > 0)
|
{
|
for (int i = 0; i < strips.length; i++)
|
{
|
s1.set(v[count3], v[count3 + 1], v[count3 + 2]);
|
count3 += 3;
|
|
s2.set(v[count3], v[count3 + 1], v[count3 + 2]);
|
count3 += 3;
|
|
for (int j = 0; j < strips[i] - 2; j++)
|
{
|
s3.set(v[count3], v[count3 + 1], v[count3 + 2]);
|
count3 += 3;
|
|
if (j%2 == 0)
|
success |= intersectTriangle(ray, result, s1, s2, s3);
|
else
|
success |= intersectTriangle(ray, result, s1, s3, s2);
|
|
s1.set(s2);
|
s2.set(s3);
|
}
|
}
|
}
|
|
assert count3 == v.length;
|
}
|
else // !trimmed
|
{
|
int count = 0;
|
for (int i = 0; i < strips.length; i++)
|
{
|
Vertex p = bRep.GetVertex(bRep.indices[count++]);
|
Vertex q = bRep.GetVertex(bRep.indices[count++]);
|
|
for (int j = 0; j < strips[i] - 2; j++)
|
{
|
Vertex r = bRep.GetVertex(bRep.indices[count++]);
|
|
if (j%2 == 0)
|
success |= intersectTriangle(ray, result, p, q, r);
|
else
|
success |= intersectTriangle(ray, result, p, r, q);
|
|
p = q;
|
q = r;
|
}
|
}
|
}
|
} else // catch (Error e)
|
{
|
int facecount = bRep.FaceCount();
|
for (int i = 0; i < facecount; i++)
|
{
|
Face face = bRep.GetFace(i);
|
|
Vertex p = bRep.GetVertex(face.p);
|
Vertex q = bRep.GetVertex(face.q);
|
Vertex r = bRep.GetVertex(face.r);
|
|
success |= intersectTriangle(ray, result, p, q, r);
|
}
|
}
|
|
return success;
|
}
|
|
static cVector eye = new cVector();
|
static cVector dir = new cVector();
|
|
transient BBox bbox = null;
|
|
boolean intersect(Ray ray, IntersectResult result)
|
{
|
double eyex = ray.eyePoint.x;
|
double eyey = ray.eyePoint.y;
|
double eyez = ray.eyePoint.z;
|
|
double dirx = ray.viewDirection.x;
|
double diry = ray.viewDirection.y;
|
double dirz = ray.viewDirection.z;
|
|
if (this.fromParent != null)
|
{
|
eye.x = eyex;
|
eye.y = eyey;
|
eye.z = eyez;
|
dir.x = dirx;
|
dir.y = diry;
|
dir.z = dirz;
|
|
LA.xformPos(eye, this.fromParent, eye);
|
LA.xformDir(dir, this.fromParent, dir);
|
|
ray.eyePoint.x = eye.x;
|
ray.eyePoint.y = eye.y;
|
ray.eyePoint.z = eye.z;
|
|
ray.viewDirection.x = dir.x;
|
ray.viewDirection.y = dir.y;
|
ray.viewDirection.z = dir.z;
|
}
|
|
boolean success = false;
|
|
boolean touch = false;
|
|
if (bRep != null)
|
{
|
if (bbox == null)
|
{
|
bbox = new BBox();
|
|
cVector min = new cVector();
|
cVector max = new cVector();
|
|
this.getBounds(min, max, false);
|
|
bbox.min.x = min.x;
|
bbox.min.y = min.y;
|
bbox.min.z = min.z;
|
|
bbox.max.x = max.x;
|
bbox.max.y = max.y;
|
bbox.max.z = max.z;
|
}
|
|
if (bbox.intersect(ray, result))
|
{
|
success |= intersectMesh(ray, result);
|
}
|
else
|
{
|
//this.hide = true;
|
touch = true;
|
}
|
}
|
|
for (int i=0; i<size(); i++)
|
{
|
Object3D child = (Object3D) reserve(i);
|
|
if (child == null)
|
continue;
|
|
success |= child.intersect(ray, result);
|
release(i);
|
}
|
|
ray.eyePoint.x = eyex;
|
ray.eyePoint.y = eyey;
|
ray.eyePoint.z = eyez;
|
|
ray.viewDirection.x = dirx;
|
ray.viewDirection.y = diry;
|
ray.viewDirection.z = dirz;
|
|
// if (touch)
|
// this.Touch(); // refresh display list
|
|
return success;
|
}
|
|
static Vector3d edge1 = new Vector3d();
|
static Vector3d edge2 = new Vector3d();
|
static Vector3d P = new Vector3d();
|
static Vector3d T = new Vector3d();
|
static Vector3d Q = new Vector3d();
|
|
private boolean intersectTriangle(Ray ray, IntersectResult result, Vertex v1, Vertex v2, Vertex v3)
|
{
|
/*
|
Fast, Minimum Storage Ray/Triangle Intersection, Moller et al.
|
|
Reference: http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
|
*/
|
|
// Calculate edges of the triangle
|
edge1.set(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z);
|
edge2.set(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z);
|
|
// Calculate the determinant (U parameter)
|
P.cross(ray.viewDirection, edge2);
|
double det = edge1.dot(P);
|
|
if (det > -1e-9 && det < 1e-9)
|
{
|
return false;
|
} // Ray lies in plane of triangle
|
|
double invDet = 1 / det;
|
|
// Calculate distance from vertex1 to ray origin
|
T.set(ray.eyePoint.x - v1.x, ray.eyePoint.y - v1.y, ray.eyePoint.z - v1.z);
|
|
double U = (T.dot(P)) * invDet; // Calculate U parameter
|
|
if (U < 0.f || U > 1.f)
|
{
|
return false;
|
} // Intersection lies outside of the triangle
|
|
// Calculate V parameter
|
Q.cross(T, edge1);
|
|
double V = ray.viewDirection.dot(Q) * invDet;
|
|
if (V < 0.f || (U + V) > 1.f)
|
{
|
return false;
|
} // Intersection lies outside of the triangle
|
|
double t = edge2.dot(Q) * invDet;
|
|
if (t > 1e-9) // Triangle and ray intersects
|
{
|
//result.isIntersected = true;
|
//result.id = id;
|
|
if (false) // isShadow)
|
{
|
result.t = t;
|
return true;
|
} else if (t < result.t)
|
{
|
result.object = this;
|
|
result.t = t;
|
|
//result.p.x = ray.eyePoint.x + ray.viewDirection.x * t;
|
//result.p.y = ray.eyePoint.y + ray.viewDirection.y * t;
|
//result.p.z = ray.eyePoint.z + ray.viewDirection.z * t;
|
|
result.n.cross(edge1, edge2);
|
result.n.normalize();
|
}
|
|
return true;
|
}
|
|
return false;
|
}
|
|
public int Size()
|
{
|
//this.elementData
|
return super.size();
|
}
|
|
public int size()
|
{
|
////GraphreeD.trace("SIZE " + this + " = ", super.size());
|
//System.out.println("SIZE = " + this + " " + super.size());
|
//assert (count >= 0);
|
if (count <= 0)
|
{
|
return 0;
|
} else
|
{
|
return super.size();
|
}
|
}
|
|
public int size0()
|
{
|
////GraphreeD.trace("SIZE " + this + " = ", super.size());
|
//System.out.println("SIZE = " + this + " " + super.size());
|
//assert (count >= 0);
|
if (count < 0)
|
{
|
return 0;
|
} else
|
{
|
return super.size();
|
}
|
}
|
|
public Object3D reserve(int i)
|
{
|
//GraphreeD.tracein("RESERVE " + this + " = ", i);
|
Object3D child = super.get(i);
|
//Applet3D.tracein("RESERVE ", child);
|
|
if (child.count <= 1) // july 2013 ??? 1) // ??? == 0)
|
return null;
|
|
child.count--;
|
//assert (child.count >= 0);
|
|
return child;
|
}
|
|
public Object3D reserve0(int i)
|
{
|
if (super.size() == 0)
|
{
|
return null;
|
}
|
|
//GraphreeD.tracein("RESERVE " + this + " = ", i);
|
Object3D child = super.get(i);
|
//Applet3D.tracein("RESERVE ", child);
|
|
if (child.count <= 0) // july 2013 ??? 1) // ??? == 0)
|
return null;
|
|
child.count--;
|
//assert (child.count >= 0);
|
|
return child;
|
}
|
|
public void release(int i)
|
{
|
//GraphreeD.traceout("RELEASE " + this + " = ", i);
|
// Object3D child = super.get(i);
|
// //Applet3D.traceout("RELEASE ", child);
|
// child.count++;
|
|
super.get(i).count++;
|
//assert (child.count >= 0);
|
}
|
|
/*
|
public synchronized int indexOf(Object elem, int index)
|
{
|
if (elem == null) {
|
for (int i = index ; i < elementCount ; i++)
|
if (elementData[i]==null)
|
return i;
|
} else {
|
for (int i = index ; i < elementCount ; i++)
|
if (((Object3D)elementData[i]).GetObject().equals(elem))
|
return i;
|
}
|
return -1;
|
}
|
*/
|
}
|