//Get a bounding box. This is used for when we display the formation continously. void FormationBhvr::GetWorldBoundBox(TimeValue t, ViewExp *vpt, Box3& box) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } //make sure we have everything we need... if(DisplayFormation(t)==FALSE) return; if(GetFollowerCount(t)<=0) return; if(GetFollowerMatrixCount(t)<=0) return; //possible to not have this set when the follower is set.. INode *leaderNode; leaderNode = GetLeader(t); if(leaderNode==NULL) return; //for each follower we need to increase the bounding box by it's //world position location... for(int i =0;i<GetFollowerCount(t);i++) { if(GetFollower(t,i)) //if we have a a node... { Matrix3 worldSpace = GetFollowerMatrix(t,i)*GetCurrentMatrix(leaderNode,t); Point3 trans(worldSpace.GetTrans()); //expand the box by the worldposition... box += trans; } } }
//The display function that is used to display the formation. int FormationBhvr::Display(TimeValue t, ViewExp *vpt) { // setup int i,j; if(DisplayFormation(t)==FALSE) return FALSE; if(GetFollowerCount(t)<=0) return FALSE; if(GetFollowerMatrixCount(t)<=0) return FALSE; INode *leaderNode; leaderNode = GetLeader(t); if(leaderNode==NULL) return FALSE; //check tgo see if we have created a default sphere for drawing yet... //if we haven't then create it.. if (numpts == 0) GetSpherePoints(Point3(0.0f,0.0f,0.0f), 1.0, SpherePts); GraphicsWindow *gw = vpt->getGW(); //set the identity matrix... Matrix3 idMat; idMat.IdentityMatrix(); gw->setTransform(idMat); gw->setColor(LINE_COLOR,.815f,.976f,1.0f); float scaleRadius = GetDisplayScale(t); //set the drawing radius values based upon what the radius size is. for (i=0; i<NUMAROUND * 3; i++) ScaledPts[i] = ((SpherePts[i] * scaleRadius)); //for each follower we need to increase the bounding box by it's //world position location... for(i =0;i<GetFollowerCount(t);i++) { INode *followerNode = GetFollower(t,i); if(followerNode) //if we have a a node... { Matrix3 leaderMat = GetCurrentMatrix(leaderNode,t); leaderMat.NoScale(); Matrix3 followerMat = GetFollowerMatrix(t,i); Matrix3 worldSpace = followerMat *leaderMat; for (j=0; j<NUMAROUND * 3; j++) CurPts[j] = worldSpace*ScaledPts[j]; //adding the center to the point positions gw->polyline(NUMAROUND,&CurPts[0],NULL,NULL,TRUE,NULL); gw->polyline(NUMAROUND,&CurPts[NUMAROUND],NULL,NULL,TRUE,NULL); gw->polyline(NUMAROUND,&CurPts[NUMAROUND * 2],NULL,NULL,TRUE,NULL); } } return TRUE; }
//This will set the formation void FormationBhvr::SetFormation(TimeValue t) { INode *node; Matrix3 tempMatrix; //Make sure that the leader is not part of the follower array.. RemoveLeaderFromFormation(t); INode *leader = GetLeader(t); if(leader==NULL) return; Matrix3 leaderPosition = GetCurrentMatrix(leader,t); leaderPosition.NoScale(); //kill any scale if we have it leaderPosition.Invert(); //it's inverted... int numDelegates = GetFollowerCount(t); //zero out the formation matrix that's used for saving it out. pblock->ZeroCount(follower_matrix1); pblock->ZeroCount(follower_matrix2); pblock->ZeroCount(follower_matrix3); pblock->ZeroCount(follower_matrix4); for(int i =0;i<numDelegates;i++) { node = GetFollower(t,i); if(node) { tempMatrix = GetCurrentMatrix(node,t); tempMatrix.NoScale(); Matrix3 leaderMat =tempMatrix*leaderPosition; AppendFollowerMatrix(t,leaderMat); //killed because matrix3 wasn't working ...pblock->Append(follower_matrix,1,&leaderMat); } else { //we still set up follower_matrix so that the counts //of the follower_matrix tab and the follower tab are equal. tempMatrix.IdentityMatrix(); AppendFollowerMatrix(t,tempMatrix); //pblock->Append(follower_matrix,1,&tempMat); } } }
//actions //make sure the leader isn't in the formation itself. void FormationBhvr::RemoveLeaderFromFormation(TimeValue t) { INode *leader = GetLeader(t); int numDelegates = GetFollowerCount(t); //we count backwards so we can simply remove it. for(int i=numDelegates-1;i>-1;--i) { if(GetFollower(t,i)==leader) { DeleteFollower(t,i); break;//only one } } }
//Given a node find the local formation matrix for it. //If the node isn't in the formation, then return a FALSE. BOOL FormationBhvr::FindFollowerMatrix(TimeValue t,INode *node,Matrix3 &mat) { //linear search through the nodes. We could get fancy //and sort the node list and do a binary search,or create a hash table //but we aren't :) int followerCount = GetFollowerCount(t); if(followerCount==0||GetFollowerMatrixCount(t)==0) return FALSE; int i; for(i=0;i<followerCount;i++) { if(GetFollower(t,i)==node) break; } if(i!=followerCount) //we found it. { mat = GetFollowerMatrix(t,i); return TRUE; } return FALSE; }