// parm3 is number of points // top left=top ccw, top right=top cw, bottom left=bottom cw, bottom right=bottom ccw void ModelClass::InitStar() { if (parm3 < 2) parm3=2; // need at least 2 arms SetNodeCount(parm1,parm2); int numlights=parm1*parm2; SetBufferSize(numlights+1,numlights+1); int LastStringNum=-1; int chan,cursegment,nextsegment,x,y; int offset=numlights/2; int numsegments=parm3*2; double segstart_x,segstart_y,segend_x,segend_y,segstart_pct,segend_pct,r,segpct,dseg; double dpct=1.0/(double)numsegments; double OuterRadius=offset; double InnerRadius=OuterRadius/2.618034; // divide by golden ratio squared double pct=isBotToTop ? 0.5 : 0.0; // % of circle, 0=top double pctIncr=1.0 / (double)numlights; // this is cw if (IsLtoR != isBotToTop) pctIncr*=-1.0; // adjust to ccw int ChanIncr=SingleChannel ? 1 : 3; size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { if (Nodes[n]->StringNum != LastStringNum) { LastStringNum=Nodes[n]->StringNum; chan=stringStartChan[LastStringNum]; } Nodes[n]->ActChan=chan; chan+=ChanIncr; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { cursegment=(int)((double)numsegments*pct) % numsegments; nextsegment=(cursegment+1) % numsegments; segstart_pct=(double)cursegment / numsegments; segend_pct=(double)nextsegment / numsegments; dseg=pct - segstart_pct; segpct=dseg / dpct; r=cursegment%2==0 ? OuterRadius : InnerRadius; segstart_x=r*sin(segstart_pct*2.0*M_PI); segstart_y=r*cos(segstart_pct*2.0*M_PI); r=nextsegment%2==0 ? OuterRadius : InnerRadius; segend_x=r*sin(segend_pct*2.0*M_PI); segend_y=r*cos(segend_pct*2.0*M_PI); // now interpolate between segstart and segend x=(segend_x - segstart_x)*segpct + segstart_x + offset + 0.5; y=(segend_y - segstart_y)*segpct + segstart_y + offset + 0.5; Nodes[n]->Coords[c].bufX=x; Nodes[n]->Coords[c].bufY=y; pct+=pctIncr; if (pct >= 1.0) pct-=1.0; if (pct < 0.0) pct+=1.0; } } }
/***************************************************** *类型:公有成员函数 *功能:定位到指定数据节点的开始位置. ***************************************************/ bool MyFile::SeekToNodeIndexBegin(int NodeIndex) { if (NodeIndex >= GetNodeCount()) return false; if (NodeIndex < 0) return false; if (!this->file) return false; fseek(file, FILEHEADERSIZE + DATANODESIZE * NodeIndex, SEEK_SET ); return true; }
int ModelClass::FindChannelAt(int x, int y) { size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { //?? if ((Nodes[n]->Coords[c].screenX == x) && (Nodes[n]->Coords[c].screenY == y)) return Nodes[n].ActChan; if ((Nodes[n]->Coords[c].bufX == x) && (Nodes[n]->Coords[c].bufY == y)) return Nodes[n]->ActChan; } } return -1; //not found }
// initialize screen coordinates void ModelClass::CopyBufCoord2ScreenCoord() { size_t NodeCount=GetNodeCount(); int xoffset=BufferWi/2; for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { Nodes[n]->Coords[c].screenX = Nodes[n]->Coords[c].bufX - xoffset; Nodes[n]->Coords[c].screenY = Nodes[n]->Coords[c].bufY; } } SetRenderSize(BufferHt,BufferWi); }
/** * * @brief * * @param[out] tree * created upgma tree. will be allocated here. use FreeMuscleTree() * to free * @param[in] mseq * @param[in] ftree * * @return non-zero on error * */ int GuideTreeFromFile(tree_t **tree, mseq_t *mseq, char *ftree) { int iNodeCount; int iNodeIndex; (*tree) = (tree_t *) CKMALLOC(1 * sizeof(tree_t)); if (MuscleTreeFromFile((*tree), ftree)!=0) { Log(&rLog, LOG_ERROR, "%s", "MuscleTreeFromFile failed"); return -1; } /* Make sure tree is rooted */ if (!IsRooted((*tree))) { Log(&rLog, LOG_ERROR, "User tree must be rooted"); return -1; } if ((int)GetLeafCount((*tree)) != mseq->nseqs) { Log(&rLog, LOG_ERROR, "User tree does not match input sequences"); return -1; } /* compare tree labels and sequence names and set leaf-ids */ iNodeCount = GetNodeCount((*tree)); for (iNodeIndex = 0; iNodeIndex < iNodeCount; ++iNodeIndex) { char *LeafName; int iSeqIndex; if (!IsLeaf(iNodeIndex, (*tree))) continue; LeafName = GetLeafName(iNodeIndex, (*tree)); if ((iSeqIndex=FindSeqName(LeafName, mseq))==-1) { Log(&rLog, LOG_ERROR, "Label '%s' in tree could not be found in sequence names", LeafName); return -1; } SetLeafId((*tree), iNodeIndex, iSeqIndex); } if (rLog.iLogLevelEnabled <= LOG_DEBUG) { Log(&rLog, LOG_DEBUG, "tree logging..."); LogTree((*tree), LogGetFP(&rLog, LOG_DEBUG)); } return 0; }
// Set screen coordinates for arches void ModelClass::SetArchCoord() { int xoffset,x,y; int numlights=parm1*parm2; size_t NodeCount=GetNodeCount(); SetRenderSize(parm2,numlights*2); double midpt=parm2; for(size_t n=0; n<NodeCount; n++) { xoffset=Nodes[n]->StringNum*parm2*2 - numlights; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { double angle=-M_PI/2.0 + M_PI * (double)Nodes[n]->Coords[c].bufX/midpt; x=xoffset + (int)floor(midpt*sin(angle)+midpt); y=(int)floor(midpt*cos(angle)+0.5); Nodes[n]->Coords[c].screenX=x; Nodes[n]->Coords[c].screenY=y; } } }
Scalar SoftBody::_ComputeVolume() const { static const Scalar fInv6 = MathFn->Invert( 6.0f ); if ( GetNodeCount() == 0 ) return 0.0f; const Vertex3 & vOrigin = GetNode(0)->Position; Vector3 vCross; Scalar fVolume = 0.0f; EnumFacets(); const Facet * pFacet = EnumNextFacet(); while( pFacet != NULL ) { vCross = ( (pFacet->GetNode(1)->Position - vOrigin) ^ (pFacet->GetNode(2)->Position - vOrigin) ); fVolume += ( (pFacet->GetNode(0)->Position - vOrigin) * vCross ); pFacet = EnumNextFacet(); } fVolume *= fInv6; return fVolume; }
// initialize screen coordinates // parm1=Number of Strings/Arches // parm2=Pixels Per String/Arch void ModelClass::SetLineCoord() { int x,y; int idx=0; size_t NodeCount=GetNodeCount(); int numlights=parm1*parm2; int half=numlights/2; SetRenderSize(numlights*2,numlights); double radians=toRadians(PreviewRotation); for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { x=cos(radians)*idx; x=IsLtoR ? x - half : half - x; y=sin(radians)*idx; Nodes[n]->Coords[c].screenX=x; Nodes[n]->Coords[c].screenY=y + numlights; idx++; } } }
void ArchesModel::SetArchCoord() { double xoffset,x,y; size_t NodeCount=GetNodeCount(); double midpt=parm2*parm3; midpt -= 1.0; midpt /= 2.0; double total = toRadians(arc); double start = (M_PI - total) / 2.0; double angle=-M_PI/2.0 + start; x=midpt*sin(angle)*2.0+parm2*parm3; double width = parm2*parm3*2 - x; double minY = 999999; for(size_t n=0; n<NodeCount; n++) { xoffset=Nodes[n]->StringNum*width; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { double angle=-M_PI/2.0 + start + total * ((double)(Nodes[n]->Coords[c].bufX * parm3 + c))/midpt/2.0; x=xoffset + midpt*sin(angle)*2.0+parm2*parm3; y=(parm2*parm3)*cos(angle); Nodes[n]->Coords[c].screenX=x; Nodes[n]->Coords[c].screenY=y; minY = std::min(minY, y); } } float renderHt = parm2*parm3; if (minY > 1) { renderHt -= minY; for (auto it = Nodes.begin(); it != Nodes.end(); it++) { for (auto coord = (*it)->Coords.begin(); coord != (*it)->Coords.end(); coord++) { coord->screenY -= minY; } } } screenLocation.SetRenderSize(width*parm1, renderHt); }
// top left=top ccw, top right=top cw, bottom left=bottom cw, bottom right=bottom ccw void ModelClass::InitWreath() { SetNodeCount(parm1,parm2); int numlights=parm1*parm2; SetBufferSize(numlights+1,numlights+1); int LastStringNum=-1; int offset=numlights/2; double r=offset; int chan,x,y; double pct=isBotToTop ? 0.5 : 0.0; // % of circle, 0=top double pctIncr=1.0 / (double)numlights; // this is cw if (IsLtoR != isBotToTop) pctIncr*=-1.0; // adjust to ccw int ChanIncr=SingleChannel ? 1 : 3; size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { if (Nodes[n]->StringNum != LastStringNum) { LastStringNum=Nodes[n]->StringNum; chan=stringStartChan[LastStringNum]; } Nodes[n]->ActChan=chan; chan+=ChanIncr; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { x=r*sin(pct*2.0*M_PI) + offset + 0.5; y=r*cos(pct*2.0*M_PI) + offset + 0.5; Nodes[n]->Coords[c].bufX=x; Nodes[n]->Coords[c].bufY=y; pct+=pctIncr; if (pct >= 1.0) pct-=1.0; if (pct < 0.0) pct+=1.0; } } }
void PixelBufferClass::InitBuffer(wxXmlNode* ModelNode) { size_t i; wxClientDC dc(DrawWindow); dc.Clear(); SetFromXml(ModelNode); pixels.resize(BufferHt * BufferWi); size_t NodeCount=GetNodeCount(); uint8_t offset_r=RGBorder.find(wxT("R")); uint8_t offset_g=RGBorder.find(wxT("G")); uint8_t offset_b=RGBorder.find(wxT("B")); for(i=0; i<NodeCount; i++) { Nodes[i].SetOffset(offset_r, offset_g, offset_b); Nodes[i].sparkle = rand() % 10000; } for(i=0; i<2; i++) { BarState[i]=0; ButterflyState[i]=0; ColorWashState[i]=0; GarlandsState[i]=0; MeteorState[i]=0; SpiralState[i]=0; } }
// initialize screen coordinates for tree void TreeModel::SetTreeCoord(long degrees) { double bufferX, bufferY; if (BufferWi < 1) return; if (BufferHt < 1) return; // June 27,2013. added check to not divide by zero double RenderHt, RenderWi; if (degrees > 0) { double angle; RenderHt=BufferHt * 3; RenderWi=((double)RenderHt)/1.8; double radians=toRadians(degrees); double radius=RenderWi/2.0; double topradius=radius/botTopRatio; double StartAngle=-radians/2.0; double AngleIncr=radians/double(BufferWi); if (degrees < 350 && BufferWi > 1) { AngleIncr=radians/double(BufferWi - 1); } //shift a tiny bit to make the strands in back not line up exactly with the strands in front StartAngle += toRadians(rotation); std::vector<float> yPos(BufferHt); std::vector<float> xInc(BufferHt); for (int x = 0; x < BufferHt; x ++) { yPos[x] = x; xInc[x] = 0; } if (spiralRotations != 0.0f) { std::vector<float> lengths(10); float rgap = (radius - topradius)/ 10.0; float total = 0; for (int x = 0; x < 10; x++) { lengths[x] = 2.0*M_PI*(radius - rgap*x) - rgap/2.0; lengths[x] *= spiralRotations / 10.0; lengths[x] = sqrt(lengths[x]*lengths[x]+(float)BufferHt/10.0*(float)BufferHt/10.0); total += lengths[x]; } int lights = 0; for (int x = 0; x < 10; x++) { lengths[x] /= total; lights += (int)std::round(lengths[x]*BufferHt); } int curSeg = 0; float lightsInSeg = std::round(lengths[0]*BufferHt); int curLightInSeg = 0; for (int x = 1; x < BufferHt; x++) { if (curLightInSeg >= lightsInSeg) { curSeg++; curLightInSeg = 0; lightsInSeg = std::round(lengths[curSeg]*BufferHt); } float ang = spiralRotations * 2.0 * M_PI / 10.0; ang /= (float)lightsInSeg; yPos[x] = yPos[x-1] + (BufferHt/10.0/lightsInSeg); xInc[x] = xInc[x-1] + ang; curLightInSeg++; } } double topYoffset = std::abs(perspective * topradius * cos(M_PI)); double ytop = RenderHt - topYoffset; double ybot = std::abs(perspective * radius * cos(M_PI)); size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { bufferX=Nodes[n]->Coords[c].bufX; bufferY=Nodes[n]->Coords[c].bufY; angle=StartAngle + double(bufferX) * AngleIncr + xInc[bufferY]; double xb=radius * sin(angle); double xt=topradius * sin(angle); double yb = ybot - perspective * radius * cos(angle); double yt = ytop - perspective * topradius * cos(angle); double posOnString = 0.5; if (BufferHt > 1) { posOnString = yPos[bufferY]/(double)(BufferHt-1.0); } Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString; Nodes[n]->Coords[c].screenY = yb + (yt - yb) * posOnString - ((double)RenderHt)/2.0; } } } else { double treeScale = degrees == -1 ? 5.0 : 4.0; double botWid = BufferWi * treeScale; RenderHt=BufferHt * 2.0; RenderWi=(botWid + 2); double offset = 0.5; size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { size_t CoordCount=GetCoordCount(n); if (degrees == -1) { for(size_t c=0; c < CoordCount; c++) { bufferX=Nodes[n]->Coords[c].bufX; bufferY=Nodes[n]->Coords[c].bufY; double xt = (bufferX + offset - BufferWi/2.0) * 0.9; double xb = (bufferX + offset - BufferWi/2.0) * treeScale; double h = std::sqrt(RenderHt * RenderHt + (xt - xb)*(xt - xb)); double posOnString = 0.5; if (BufferHt > 1) { posOnString = (bufferY/(double)(BufferHt-1.0)); } double newh = RenderHt * posOnString; Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString; Nodes[n]->Coords[c].screenY = RenderHt * newh / h - ((double)RenderHt)/2.0; posOnString = 0; if (BufferHt > 1) { posOnString = ((bufferY - 0.33)/(double)(BufferHt-1.0)); } newh = RenderHt * posOnString; Nodes[n]->Coords.push_back(Nodes[n]->Coords[c]); Nodes[n]->Coords.back().screenX = xb + (xt - xb) * posOnString; Nodes[n]->Coords.back().screenY = RenderHt * newh / h - ((double)RenderHt)/2.0; posOnString = 1; if (BufferHt > 1) { posOnString = ((bufferY + 0.33)/(double)(BufferHt-1.0)); } newh = RenderHt * posOnString; Nodes[n]->Coords.push_back(Nodes[n]->Coords[c]); Nodes[n]->Coords.back().screenX = xb + (xt - xb) * posOnString; Nodes[n]->Coords.back().screenY = RenderHt * newh / h - ((double)RenderHt)/2.0; } } else { for(size_t c=0; c < CoordCount; c++) { bufferX=Nodes[n]->Coords[c].bufX; bufferY=Nodes[n]->Coords[c].bufY; double xt = (bufferX + offset - BufferWi/2.0) * 0.9; double xb = (bufferX + offset - BufferWi/2.0) * treeScale; double posOnString = 0.5; if (BufferHt > 1) { posOnString = (bufferY/(double)(BufferHt-1.0)); } Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString; Nodes[n]->Coords[c].screenY = RenderHt * posOnString - ((double)RenderHt)/2.0; } } } } screenLocation.SetRenderSize(RenderWi, RenderHt); }
wxString ModelClass::ChannelLayoutHtml() { size_t NodeCount=GetNodeCount(); size_t i,idx; int n,x,y,s; wxString bgcolor; std::vector<int> chmap; chmap.resize(BufferHt * BufferWi,0); bool IsCustom = DisplayAs == "Custom"; wxString direction; if (IsCustom) { direction="n/a"; } else if (!IsLtoR) { if(!isBotToTop) direction="Top Right"; else direction="Bottom Right"; } else { if (!isBotToTop) direction="Top Left"; else direction="Bottom Left"; } wxString html = "<html><body><table border=0>"; html+="<tr><td>Name:</td><td>"+name+"</td></tr>"; html+="<tr><td>Display As:</td><td>"+DisplayAs+"</td></tr>"; html+="<tr><td>String Type:</td><td>"+StringType+"</td></tr>"; html+="<tr><td>Start Corner:</td><td>"+direction+"</td></tr>"; html+=wxString::Format("<tr><td>Total nodes:</td><td>%d</td></tr>",NodeCount); html+=wxString::Format("<tr><td>Height:</td><td>%d</td></tr>",BufferHt); html+="</table><p>Node numbers starting with 1 followed by string number:</p><table border=1>"; if (BufferHt == 1) { // single line or arch html+="<tr>"; for(i=1; i<=NodeCount; i++) { n=IsLtoR ? i : NodeCount-i+1; s=Nodes[n-1]->StringNum+1; bgcolor=s%2 == 1 ? "#ADD8E6" : "#90EE90"; html+=wxString::Format("<td bgcolor='"+bgcolor+"'>n%ds%d</td>",n,s); } html+="</tr>"; } else if (BufferHt > 1) { // horizontal or vertical matrix or frame for(i=0; i<NodeCount; i++) { idx=Nodes[i]->Coords[0].bufY * BufferWi + Nodes[i]->Coords[0].bufX; if (idx < chmap.size()) chmap[idx]=GetNodeNumber(i); } for(y=BufferHt-1; y>=0; y--) { html+="<tr>"; for(x=0; x<BufferWi; x++) { n=chmap[y*BufferWi+x]; if (n==0) { html+="<td></td>"; } else { s=Nodes[n-1]->StringNum+1; bgcolor=s%2 == 1 ? "#ADD8E6" : "#90EE90"; html+=wxString::Format("<td bgcolor='"+bgcolor+"'>n%ds%d</td>",n,s); } } html+="</tr>"; } } else { html+="<tr><td>Error - invalid height</td></tr>"; } html+="</table></body></html>"; return html; }
int ModelClass::GetChanCount() { size_t NodeCnt=GetNodeCount(); return NodeCnt==0 ? 0 : NodeCnt * Nodes[0]->GetChanCount(); }
// initialize buffer coordinates // parm1=Nodes on Top // parm2=Nodes left and right // parm3=Nodes on Bottom void ModelClass::InitFrame() { int x,y,newx,newy; SetNodeCount(1,parm1+2*parm2+parm3); int FrameWidth=std::max(parm1,parm3)+2; SetBufferSize(parm2,FrameWidth); // treat as outside of matrix //SetBufferSize(1,Nodes.size()); // treat as single string SetRenderSize(parm2,FrameWidth); int chan=stringStartChan[0]; int ChanIncr=SingleChannel ? 1 : 3; int xincr[4]= {0,1,0,-1}; // indexed by side int yincr[4]= {1,0,-1,0}; x=IsLtoR ? 0 : FrameWidth-1; y=isBotToTop ? 0 : parm2-1; int dir=1; // 1=clockwise int side=x>0 ? 2 : 0; // 0=left, 1=top, 2=right, 3=bottom int SideIncr=1; // 1=clockwise if ((parm1 > parm3 && x>0) || (parm3 > parm1 && x==0)) { // counter-clockwise dir=-1; SideIncr=3; } // determine starting position if (parm1 > parm3) { // more nodes on top, must start at bottom y=0; } else if (parm3 > parm1) { // more nodes on bottom, must start at top y=parm2-1; } else { // equal top and bottom, can start in any corner // assume clockwise numbering if (x>0 && y==0) { // starting in lower right side=3; } else if (x==0 && y>0) { // starting in upper left side=1; } } size_t NodeCount=GetNodeCount(); for(size_t n=0; n<NodeCount; n++) { Nodes[n]->ActChan=chan; chan+=ChanIncr; size_t CoordCount=GetCoordCount(n); for(size_t c=0; c < CoordCount; c++) { Nodes[n]->Coords[c].bufX=x; Nodes[n]->Coords[c].bufY=y; newx=x+xincr[side]*dir; newy=y+yincr[side]*dir; if (newx < 0 || newx >= FrameWidth || newy < 0 || newy >= parm2) { // move to the next side side=(side+SideIncr) % 4; newx=x+xincr[side]*dir; newy=y+yincr[side]*dir; } x=newx; y=newy; } } }
void TaxiPath::SendMoveForTime(Player *riding, Player *to, uint32 time) { if (!time) return; float traveled_len = (time/(getLength() * TAXI_TRAVEL_SPEED))*getLength();; uint32 len = 0, count = 0; float x = 0,y = 0,z = 0; if (!m_pathNodes.size()) return; std::map<uint32, TaxiPathNode*>::iterator itr; itr = m_pathNodes.begin(); float nx = itr->second->x; float ny = itr->second->y; float nz = itr->second->z; itr++; while (itr != m_pathNodes.end()) { len = (uint32)sqrt((itr->second->x - nx)*(itr->second->x - nx) + (itr->second->y - ny)*(itr->second->y - ny) + (itr->second->z - nz)*(itr->second->z - nz)); if (len > traveled_len) { x = (itr->second->x - nx)*(traveled_len/len) + nx; y = (itr->second->y - ny)*(traveled_len/len) + ny; z = (itr->second->z - nz)*(traveled_len/len) + nz; break; } else { traveled_len -= len; } nx = itr->second->x; ny = itr->second->y; nz = itr->second->z; itr++; count++; } if (itr == m_pathNodes.end()) return; WorldPacket * data = new WorldPacket(SMSG_MONSTER_MOVE, 2000); *data << riding->GetNewGUID(); *data << riding->GetPositionX( ) << riding->GetPositionY( ) << riding->GetPositionZ( ); *data << getMSTime(); *data << uint8( 0 ); *data << uint32( 0x00000300 ); *data << uint32( uint32((getLength() * TAXI_TRAVEL_SPEED) - time)); *data << uint32( GetNodeCount() - count ); *data << nx << ny << nz; while (itr != m_pathNodes.end()) { TaxiPathNode *pn = itr->second; *data << pn->x << pn->y << pn->z; itr++; } //to->GetSession()->SendPacket(&data); to->delayedPackets.add(data); }
Void SoftBody::_SetupPose( Bool bIsVolume, Bool bIsFrame ) { const Node * pNode; UInt iNodeIndex; // Update links EnumLinks(); Link * pLink = EnumNextLink(); while( pLink != NULL ) { pLink->UpdateConstants(); pLink = EnumNextLink(); } // Compute total mass Scalar fTotalMass = _ComputeMass(); Scalar fMassK = fTotalMass * 1000.0f * (Scalar)( GetNodeCount() ); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { if ( pNode->InvMass == 0.0f ) fTotalMass += fMassK; pNode = EnumNextNode(); } Scalar fInvTotalMass = MathFn->Invert( fTotalMass ); // Flags m_hPose.bIsVolume = bIsVolume; m_hPose.bIsFrame = bIsFrame; // Weights m_hPose.arrWeights.Clear(); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { if ( pNode->InvMass > 0.0f ) m_hPose.arrWeights.Push( pNode->Mass * fInvTotalMass ); else m_hPose.arrWeights.Push( fMassK * fInvTotalMass ); pNode = EnumNextNode(); } // COM m_hPose.vCenterOfMass = _ComputeCenterOfMass(); // Deltas m_hPose.arrDeltas.Clear(); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { m_hPose.arrDeltas.Push( pNode->Position - m_hPose.vCenterOfMass ); pNode = EnumNextNode(); } // Volume m_hPose.fVolume = ( (bIsVolume) ? _ComputeVolume() : 0.0f ); // BaseScaling Matrix3 matBaseScaling; matBaseScaling.MakeNull(); Vector3 vTmpRow; EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { iNodeIndex = pNode->GetIndex(); const Vector3 & vDelta = m_hPose.arrDeltas[iNodeIndex]; const Vector3 & vWeightedDelta = ( vDelta * m_hPose.arrWeights[iNodeIndex] ); matBaseScaling.GetRow( vTmpRow, 0 ); matBaseScaling.SetRow( 0, vTmpRow + (vDelta * vWeightedDelta.X) ); matBaseScaling.GetRow( vTmpRow, 1 ); matBaseScaling.SetRow( 1, vTmpRow + (vDelta * vWeightedDelta.Y) ); matBaseScaling.GetRow( vTmpRow, 2 ); matBaseScaling.SetRow( 2, vTmpRow + (vDelta * vWeightedDelta.Z) ); pNode = EnumNextNode(); } matBaseScaling.Invert( m_hPose.matBaseScaling ); // Rotation & Scaling m_hPose.matRotation.MakeIdentity(); m_hPose.matScaling.MakeIdentity(); }
const int SystemVSM :: GetMajorityCount() const { return (int)(floor((double)GetNodeCount() / 2) + 1); }
void ModelClass::SetFromXml(wxXmlNode* ModelNode, bool zeroBased) { wxString tempstr,channelstr; wxString customModel,RGBorder; long degrees, StartChannel, channel; size_t i; ModelXml=ModelNode; TreeDegrees=0; StrobeRate=0; Nodes.clear(); name=ModelNode->GetAttribute("name"); DisplayAs=ModelNode->GetAttribute("DisplayAs"); if (ModelNode->HasAttribute("StringType")) { // post 3.1.4 StringType=ModelNode->GetAttribute("StringType"); } else { // 3.1.4 and earlier StringType=ModelNode->GetAttribute("Order","RGB")+" Nodes"; } SingleNode=HasSingleNode(StringType); SingleChannel=HasSingleChannel(StringType); RGBorder=SingleNode ? "RGB" : RGBorder=StringType.Left(3); rgbidx[0]=std::max(RGBorder.Find('R'),0); rgbidx[1]=std::max(RGBorder.Find('G'),0); rgbidx[2]=std::max(RGBorder.Find('B'),0); tempstr=ModelNode->GetAttribute("parm1"); tempstr.ToLong(&parm1); tempstr=ModelNode->GetAttribute("parm2"); tempstr.ToLong(&parm2); tempstr=ModelNode->GetAttribute("parm3"); tempstr.ToLong(&parm3); tempstr=ModelNode->GetAttribute("StartChannel","1"); tempstr.ToLong(&StartChannel); tempstr=ModelNode->GetAttribute("Dir"); IsLtoR=tempstr != "R"; if (ModelNode->HasAttribute("StartSide")) { tempstr=ModelNode->GetAttribute("StartSide"); isBotToTop = (tempstr == "B"); } else { isBotToTop=true; } tempstr=ModelNode->GetAttribute("Antialias","0"); tempstr.ToLong(&Antialias); AliasFactor=1 << Antialias; MyDisplay=IsMyDisplay(ModelNode); tempstr=ModelNode->GetAttribute("offsetXpct","0"); tempstr.ToDouble(&offsetXpct); tempstr=ModelNode->GetAttribute("offsetYpct","0"); tempstr.ToDouble(&offsetYpct); tempstr=ModelNode->GetAttribute("PreviewScale","0.333"); tempstr.ToDouble(&PreviewScale); tempstr=ModelNode->GetAttribute("PreviewRotation","0"); tempstr.ToLong(°rees); PreviewRotation=degrees; // calculate starting channel numbers for each string size_t NumberOfStrings= HasOneString(DisplayAs) ? 1 : parm1; int ChannelsPerString=parm2*3; if (SingleChannel) ChannelsPerString=1; else if (SingleNode) ChannelsPerString=3; if (ModelNode->HasAttribute("CustomModel")) { customModel = ModelNode->GetAttribute("CustomModel"); int maxval=GetCustomMaxChannel(customModel); // fix NumberOfStrings if (SingleNode) { NumberOfStrings=maxval; } else { ChannelsPerString=maxval*3; } } tempstr=ModelNode->GetAttribute("Advanced","0"); bool HasIndividualStartChans=tempstr == "1"; stringStartChan.clear(); stringStartChan.resize(NumberOfStrings); for (i=0; i<NumberOfStrings; i++) { tempstr=StartChanAttrName(i); if (!zeroBased && HasIndividualStartChans && ModelNode->HasAttribute(tempstr)) { ModelNode->GetAttribute(tempstr, &channelstr); channelstr.ToLong(&channel); stringStartChan[i] = channel-1; } else { stringStartChan[i] = (zeroBased? 0 : StartChannel-1) + i*ChannelsPerString; } } // initialize model based on the DisplayAs value wxStringTokenizer tkz(DisplayAs, " "); wxString token = tkz.GetNextToken(); if (token == "Tree") { InitVMatrix(); token = tkz.GetNextToken(); token.ToLong(°rees); SetTreeCoord(degrees); } else if (DisplayAs == "Custom") { InitCustomMatrix(customModel); CopyBufCoord2ScreenCoord(); } else if (DisplayAs == "Vert Matrix") { InitVMatrix(); CopyBufCoord2ScreenCoord(); } else if (DisplayAs == "Horiz Matrix") { InitHMatrix(); CopyBufCoord2ScreenCoord(); } else if (DisplayAs == "Single Line") { InitLine(); SetLineCoord(); } else if (DisplayAs == "Arches") { InitHMatrix(); // Old call was InitLine(); SetArchCoord(); } else if (DisplayAs == "Window Frame") { InitFrame(); CopyBufCoord2ScreenCoord(); } else if (DisplayAs == "Star") { InitStar(); CopyBufCoord2ScreenCoord(); } else if (DisplayAs == "Wreath") { InitWreath(); CopyBufCoord2ScreenCoord(); } size_t NodeCount=GetNodeCount(); for(size_t i=0; i<NodeCount; i++) { Nodes[i]->sparkle = rand() % 10000; } }
/// <summary> /// The purpose of this test is to load the "matchingtest.data" data file and run the tests laid out /// in that file, checking for failures. The "matchingtest.data" file contains a series of /// predefined selectors and html to test the selectors against. /// /// Run this test as well as GQ in debug mode to get an extreme amount of information about the /// internals of the parser, selector construction, etc. To get this additional information, ensure /// that while compiling GQ in debug mode, you add "GQ_VERBOSE_DEBUG_NFO" to the preprocessor /// definitions. The verbose output can help gain much insight when debugging selectors and /// the internals of GQ. /// </summary> int main() { std::string matchingTestDataFilePath(u8"../../matchingtest.data"); std::ifstream in(matchingTestDataFilePath, std::ios::binary | std::ios::in); if (in.fail()) { std::cout << u8"Failed to load \"../../matchingtest.data\" test file." << std::endl; return -1; } std::vector<int> testNumbers; std::vector<std::string> testSelectors; std::vector< std::pair<bool, int> > testExpectedMatches; std::vector<std::string> testHtmlSamples; std::string testContents; in.seekg(0, std::ios::end); auto fsize = in.tellg(); if (fsize < 0 || static_cast<unsigned long long>(fsize) > static_cast<unsigned long long>(std::numeric_limits<size_t>::max())) { std::cout << u8"When loading the test file, ifstream::tellg() returned either less than zero or a number greater than this program can correctly handle." << std::endl; return -1; } testContents.resize(static_cast<size_t>(fsize)); in.seekg(0, std::ios::beg); in.read(&testContents[0], testContents.size()); in.close(); std::istringstream tests(testContents); std::string test; while (std::getline(tests, test)) { if (test.length() == 0 || test[0] == '!') { // Skip empty lines and comments continue; } std::istringstream isstest(test); std::string testPart; while (std::getline(isstest, testPart, '%')) { auto splitPos = testPart.find('@'); auto testVariable = testPart.substr(0, splitPos); auto testVariableValue = testPart.substr(splitPos + 1); if (testVariable.length() == 0 || testVariableValue.length() == 0) { std::cout << u8"Empty test variable or value encountered. Test file is improperly formatted. Aborting." << std::endl; return -1; } if (testVariable.compare(u8"TestNumber") == 0) { testNumbers.push_back(std::stoi(testVariableValue)); } else if (testVariable.compare(u8"TestSelector") == 0) { testSelectors.push_back(testVariableValue); } else if (testVariable.compare(u8"TestExpectedMatches") == 0) { testExpectedMatches.push_back({ true, std::stoi(testVariableValue) }); } else if (testVariable.compare(u8"TestExpectedUncheckedMatches") == 0) { testExpectedMatches.push_back({ false, std::stoi(testVariableValue) }); } else if (testVariable.compare(u8"TestHtml") == 0) { testHtmlSamples.push_back(testVariableValue); } } } size_t testsPassed = 0; size_t testsFailed = 0; gq::Parser parser; if (testNumbers.size() == testSelectors.size() && testExpectedMatches.size() == testNumbers.size() && testHtmlSamples.size() == testExpectedMatches.size()) { for (size_t i = 0; i < testNumbers.size(); ++i) { for (size_t b = 0; b < 72; ++b) { std::cout << '-'; } std::cout << std::endl << u8"\t\t\t\tTest #" << testNumbers[i] << std::endl; for (size_t b = 0; b < 72; ++b) { std::cout << '-'; } std::cout << std::endl << std::endl; auto document = gq::Document::Create(); std::cout << u8"Input HTML:" << std::endl; std::cout << testHtmlSamples[i] << std::endl << std::endl; document->Parse(testHtmlSamples[i]); std::cout << u8"Parsed Output HTML:" << std::endl; std::cout << document->GetOuterHtml(); try { std::cout << std::endl; auto selector = parser.CreateSelector(testSelectors[i], true); auto result = document->Find(selector); std::cout << u8"Original Selector String: " << selector->GetOriginalSelectorString() << std::endl << std::endl; if (result.GetNodeCount() != testExpectedMatches[i].second) { std::cout << u8"Test Number " << testNumbers[i] << u8" failed using selector " << testSelectors[i] << u8" because " << testExpectedMatches[i].second << u8" matches were expected, received " << result.GetNodeCount() << std::endl << std::endl; ++testsFailed; for (size_t ri = 0; ri < result.GetNodeCount(); ++ri) { auto* node = result.GetNodeAt(ri); std::cout << gq::Serializer::Serialize(node) << std::endl; } continue; } else { // If the test pair bool is true, that means that we're not just counting results, but that we're // also validating the results. We'll check the results to see if they contain the test "FAIL". If // they do, that means that an element that should not have been selected by the selector was indeed // selected. If "FAIL" is not matched, "PASS" is assumed. if (testExpectedMatches[i].first == true) { bool foundInvalidData = false; for (size_t ri = 0; ri < result.GetNodeCount(); ++ri) { auto* node = result.GetNodeAt(ri); if (node->GetOwnText().compare("FAIL") == 0) { foundInvalidData = true; break; } std::cout << gq::Serializer::Serialize(node) << std::endl; } if (foundInvalidData) { std::cout << u8"Test Number " << testNumbers[i] << u8" failed using selector " << testSelectors[i] << u8" because although the number of expected matches was accurate, the selector matched a node it should not have." << std::endl; ++testsFailed; } else { std::cout << u8"Test Number " << testNumbers[i] << u8" passed using selector " << testSelectors[i] << u8" because the correct number of expected matches were returned the match data was confirmed." << std::endl; ++testsPassed; } } else { std::cout << u8"Test Number " << testNumbers[i] << u8" passed using selector " << testSelectors[i] << u8" because " << testExpectedMatches[i].second << u8" matches were expected, received " << result.GetNodeCount() << u8". Test does not verify results, only quantity." << std::endl; ++testsPassed; } } } catch (std::runtime_error& e) { std::cout << u8"Got runtime_error: " << e.what() << std::endl; } catch (std::exception& e) { std::cout << u8"Got exception: " << e.what() << std::endl; } } } else { std::cout << u8"An unequal number of test variables were parsed. Test file is improperly formatted. Aborting." << std::endl; return -1; } std::cout << testsPassed << u8" Tests Passed and " << testsFailed << u8" Tests Failed." << std::endl; return 0; }
/** * * @brief Depth first traversal of tree, i.e. leaf nodes (sequences) * will be visited first. Order can be used to guide progressive * alignment order. * * @param[out] piOrderLR_p * order in which left/right nodes (profiles) are to be aligned. * allocated here; caller must free. * @param[in] tree * The tree to traverse; has to be rooted * @param[in] mseq * corresponding multiple sequence structure * */ void TraverseTree(int **piOrderLR_p, tree_t *tree, mseq_t *mseq) { int tree_nodeindex = 0; int order_index = 0; assert(NULL!=tree); assert(NULL!=mseq); assert(IsRooted(tree)); /* allocate memory for node/profile alignment order; * for every node allocate DIFF_NODE (3) int (1 left, 1 right, 1 parent) */ *piOrderLR_p = (int *)CKCALLOC(DIFF_NODE * GetNodeCount(tree), sizeof(int)); /* Log(&rLog, LOG_FORCED_DEBUG, "print tree->m_iNodeCount=%d", tree->m_iNodeCount); */ tree_nodeindex = FirstDepthFirstNode(tree); /*LOG_DEBUG("Starting with treenodeindex = %d", tree_nodeindex);*/ order_index = 0; do { if (IsLeaf(tree_nodeindex, tree)) { int leafid = GetLeafId(tree_nodeindex, tree); if (leafid >= mseq->nseqs) Log(&rLog, LOG_FATAL, "Sequence index out of range during tree traversal (leafid=%d nseqs=%d)", leafid, mseq->nseqs); /* this is a leaf node, * indicate this by registering same leafid for left/right */ (*piOrderLR_p)[DIFF_NODE*order_index+LEFT_NODE] = leafid; (*piOrderLR_p)[DIFF_NODE*order_index+RGHT_NODE] = leafid; (*piOrderLR_p)[DIFF_NODE*order_index+PRNT_NODE] = tree_nodeindex; Log(&rLog, LOG_DEBUG, "Tree traversal: Visited leaf-node %d (leaf-id %d = Seq '%s')", tree_nodeindex, leafid, mseq->sqinfo[leafid].name); } else { int merge_nodeindex; int left; int right; merge_nodeindex = tree_nodeindex; left = GetLeft(tree_nodeindex, tree); right = GetRight(tree_nodeindex, tree); /* this is not a leaf node but a merge node, * register left node (even) and right node (odd) */ (*piOrderLR_p)[DIFF_NODE*order_index+LEFT_NODE] = left; (*piOrderLR_p)[DIFF_NODE*order_index+RGHT_NODE] = right; (*piOrderLR_p)[DIFF_NODE*order_index+PRNT_NODE] = merge_nodeindex; Log(&rLog, LOG_DEBUG, "Tree traversal: Visited non-leaf node %d with siblings %d (L) and %d (R)", merge_nodeindex, left, right); } tree_nodeindex = NextDepthFirstNode(tree_nodeindex, tree); order_index++; } while (NULL_NEIGHBOR != tree_nodeindex); return; }