// Abstract class for mobile nodes abstract class MobileAbstractNode { // dx, dy, dz from the origin of the parent node pt m_ptFromParent; pt m_ptFromMouse; int threadNode = 1; int barNode = 2; int customNode = 3; float m_deltaAngle = 0; float m_prevAngle = 0; int m_kind = threadNode; boolean m_selected = false; // children Vector m_childrenNode; // constructor MobileAbstractNode() { println("made abstract"); m_ptFromParent = new pt(); m_ptFromMouse = new pt(); m_childrenNode = new Vector(); m_selected = false; m_kind = threadNode; println("m_kind = " + m_kind); } // abstract functions abstract boolean IsMouseIn(float thisX, float thisY, float thisZ); abstract void ShowMenuMyself(); abstract void PressKeyMyself(); abstract void DrawMyself(); abstract void DraggedChild(float dxChild, float dyChild); abstract void AddChild(); abstract void RemoveChild(); abstract int SaveMyself(String [] buffer, int curIndex); abstract int LoadMyself(String [] buffer, int curIndex); int Save(String [] buffer, int curIndex) { // save kind buffer[curIndex++] = str(m_kind); //println("kind = "+m_kind); //m_ptFromParent buffer[curIndex++] = str(m_ptFromParent.x)+","+str(m_ptFromParent.y)+","+str(m_ptFromParent.z); //print("ptFromParent = "); m_ptFromParent.write(); //m_deltaAngle buffer[curIndex++] = str(m_deltaAngle); //println("save myslef"); curIndex = SaveMyself(buffer, curIndex); // save children buffer[curIndex++] = str(m_childrenNode.size()); //println("save children : " + m_childrenNode.size()); for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); curIndex = childNode.Save(buffer, curIndex); } return curIndex; } int Load(String[] buffer, int curIndex) { float x, y, z; //m_ptFromParent x = GetFloat(buffer[curIndex], 0); y = GetFloat(buffer[curIndex], 1); z = GetFloat(buffer[curIndex], 2); m_ptFromParent.setTo(x, y, z); //print("ptFromParent = "); //m_ptFromParent.write(); curIndex++; //m_deltaAngle m_deltaAngle = float(buffer[curIndex++]); // println("deltaAngle = " + m_deltaAngle); curIndex = LoadMyself(buffer, curIndex); // Load children m_childrenNode.clear(); int childnum = int(buffer[curIndex++]); for ( int i = 0; i < childnum; i++ ) { int kind = int(buffer[curIndex++]); MobileAbstractNode childNode = MakeNode(kind, this); curIndex = childNode.Load(buffer, curIndex); m_childrenNode.add(childNode); } return curIndex; } void SetPos(float x, float y, float z) { m_ptFromParent.setTo(x, y, z); } void SetPosX(float x) { m_ptFromParent.x = x; } void SetPosY(float y) { m_ptFromParent.y = y; } void SetPosZ(float z) { m_ptFromParent.z = z; } void MoveDelta(float deltaX, float deltaY, float deltaZ) { m_ptFromParent.x += deltaX; m_ptFromParent.y += deltaY; m_ptFromParent.z += deltaZ; } void Rotate(pt ptOrigin, float angleX, float angleY, float angleZ) { m_ptFromParent.rotateXBy(angleX, ptOrigin); m_ptFromParent.rotateYBy(angleY, ptOrigin); m_ptFromParent.rotateZBy(angleZ, ptOrigin); } float GetPosX() { return m_ptFromParent.x; } float GetPosY() { return m_ptFromParent.y; } float GetPosZ() { return m_ptFromParent.z; } void Draw() { pushMatrix(); translate(m_ptFromParent.x, m_ptFromParent.y, m_ptFromParent.z); m_prevAngle += m_deltaAngle; rotateY(PI*m_prevAngle/180); DrawMyself(); // draw children for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); childNode.Draw(); } popMatrix(); } void ShowMenu() { if ( m_selected == true ) { ShowMenuMyself(); } else { // draw children for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); childNode.ShowMenu(); } } } void Unselect() { m_selected = false; for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); childNode.Unselect(); } } boolean Select(float parentX, float parentY, float parentZ) { float thisX = parentX + m_ptFromParent.x; float thisY = parentY + m_ptFromParent.y; float thisZ = parentZ + m_ptFromParent.z; // if this node selected if ( IsMouseIn(thisX, thisY, thisZ) ) { m_selected = true; m_ptFromMouse.x = mouseX - m_ptFromParent.x; m_ptFromMouse.y = mouseY - m_ptFromParent.y; m_ptFromMouse.z = 0 - m_ptFromParent.z; //println("this : " + thisX + ", " + thisY + ", " + thisZ ); //print("mouse : "); //ptMouse3D.write(); return true; } else { for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); if ( childNode.Select(thisX, thisY, thisZ) ) { return true; } } return false; } } boolean Drag() { if ( m_selected == true ) { //m_ptFromParent.setTo(ptMouse3D); m_ptFromParent.x = mouseX-m_ptFromMouse.x; m_ptFromParent.y = mouseY-m_ptFromMouse.y; m_ptFromParent.z = 0 - m_ptFromMouse.z; //print("drag : "); //m_ptFromParent.write(); return true; } else { for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); if ( childNode.Drag() ) { // when one of children is dragged DraggedChild(childNode.GetPosX(), childNode.GetPosY()); return true; } } return false; } } boolean PressKey() { if ( m_selected == true ) { PressKeyMyself(); return true; } else { // draw children for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); if ( childNode.PressKey() == true ) return true; } } return false; } boolean IsSelected() { if ( m_selected == true ) { return true; } else { for ( int i = 0; i < m_childrenNode.size(); i++ ) { MobileAbstractNode childNode = (MobileAbstractNode)m_childrenNode.get(i); if ( childNode.IsSelected() ) return true; } } return false; } MobileAbstractNode MakeNode(int kind, MobileAbstractNode parent) { if (kind == threadNode ) { return new MobileThreadNode(); } else if ( kind == barNode ) { return new MobileBarNode(parent); } else { return new MobileCustomNode(parent); } } } float GetFloat(String string, int idx) { //println("string = "+string); int comma1, comma2; comma1=string.indexOf(','); if ( idx == 0 ) { return float(string.substring(0, comma1)); } else { String rest = string.substring(comma1+1, string.length()); comma2=rest.indexOf(','); if ( idx == 1 ) { return float(rest.substring(0, comma2)); } else { return float(rest.substring(comma2+1, rest.length())); } } }