void PageDoc::Paste(sInt x,sInt y) { sInt i,max; PageDoc *clip; PageOp *po,*copy; sInt xmin,ymin; clip = (PageDoc *)sGui->ClipboardFind(sCID_TOOL_PAGEDOC); if(clip) { max = clip->Ops->GetCount(); xmin = PAGESX; ymin = PAGESY; for(i=0;i<max;i++) { po = clip->Ops->Get(i); xmin = sMin(xmin,po->PosX); ymin = sMin(ymin,po->PosY); } if(CheckDest(clip,x-xmin,y-ymin)) { for(i=0;i<max;i++) { po = clip->Ops->Get(i); copy = new PageOp; copy->Copy(po); copy->PosX += x - xmin; copy->PosY += y - ymin; Ops->Add(copy); } } } UpdatePage(); }
// Create a pattern of randomly colored voronoi cells static void RandomVoronoi(GenTexture &dest,const GenTexture &grad,sInt intensity,sInt maxCount,sF32 minDist) { sVERIFY(maxCount <= 256); CellCenter centers[256]; // generate random center points for(sInt i=0;i<maxCount;i++) { int intens = (rand() * intensity) / RAND_MAX; centers[i].x = 1.0f * rand() / RAND_MAX; centers[i].y = 1.0f * rand() / RAND_MAX; centers[i].color.Init(intens,intens,intens,255); } // remove points too close together sF32 minDistSq = minDist*minDist; for(sInt i=1;i<maxCount;) { sF32 x = centers[i].x; sF32 y = centers[i].y; // try to find a point closer than minDist sInt j; for(j=0;j<i;j++) { sF32 dx = centers[j].x - x; sF32 dy = centers[j].y - y; if(dx < 0.0f) dx += 1.0f; if(dy < 0.0f) dy += 1.0f; dx = sMin(dx,1.0f-dx); dy = sMin(dy,1.0f-dy); if(dx*dx + dy*dy < minDistSq) // point is too close, stop break; } if(j<i) // we found such a point centers[i] = centers[--maxCount]; // remove this one else // accept this one i++; } // generate the image dest.Cells(grad,centers,maxCount,0.0f,GenTexture::CellInner); }
static void spDecompose( int iMaxDim, int iBaseDim, const PixmapRegName& iPRN, vector<PixmapRegName>& ioPRNs) { vector<ZRectPOD> theRects; // Quantized region. { ZBigRegionAccumulator quant; const int q = iBaseDim; const ZBigRegion theRgn = spRegion(iPRN.f0); const ZRectPOD theBounds = theRgn.Bounds(); const vector<ZRectPOD> decomposed = spDecompose(theRgn); foreachv (const ZRectPOD& theRect, decomposed) { const ZRectPOD current = sRectPOD( (L(theRect) / q) * q, (T(theRect) / q) * q, (R(theRect + q - 1) / q) * q, (B(theRect + q - 1) / q) * q); quant.Include(theBounds & current); } quant.Get().Decompose(theRects); } // We have a list of rectangles within the source. // Now let's break up any that are too big. vector<ZRectPOD> smallRects; foreachv (const ZRectPOD& theRect, theRects) { for (int theTop = T(theRect); theTop < B(theRect); /*no inc*/) { const int theBottom = sMin(theTop + iMaxDim, B(theRect)); for (int theLeft = L(theRect); theLeft < R(theRect); /*no inc*/) { const int theRight = sMin(theLeft + iMaxDim, R(theRect)); smallRects.push_back(sRectPOD(theLeft, theTop, theRight, theBottom)); theLeft = theRight; } theTop = theBottom; } } // Append chunks to ioPRNs foreachv (const ZRectPOD& theRect, smallRects) { ioPRNs.push_back( PixmapRegName(ZDCPixmap(iPRN.f0, theRect), iPRN.f1 - LT(theRect), iPRN.f2)); }
bool sCopyFile(const char *source,const char *dest,bool failifexists) { sFile *sf = sOpenFile(source,sFA_Read); sFile *df = sOpenFile(dest,sFA_Write); bool ok = 0; if(sf && df) { uptr size = uptr(sf->GetSize()); uptr block = 1024*1024; uint8 *buffer = new uint8[block]; while(size>0) { uptr chunk = sMin(block,size); sf->Read(buffer,chunk); df->Write(buffer,chunk); size -= chunk; } } if(sf) if(!sf->Close()) ok = 0; if(df) if(!df->Close()) ok = 0; if(!ok) sLogF("file","failed to copy file <%s> to <%s>",source,dest); else sLogF("file","copy file <%s> to <%s>",source,dest); return ok; }
static void TestSequence1(const sChar *desc,sArrayRange<sInt> &seq) { static const sInt nAttempts = 3; sStaticArray<sInt> arr(seq.GetCount()); sPrintF(L"%-12s ",desc); for(sInt i=0; i<sCOUNTOF(sortFuncs1); i++) { // report minimum runtime over nAttempts runs sInt minTime = 0x7fffffff; for(sInt j=0; j<nAttempts; j++) { arr.Clear(); sCopyMem(arr.AddMany(seq.GetCount()),&seq[0],seq.GetCount()*sizeof(sInt)); ThrashCache(); sU64 start = sGetTimeUS(); sortFuncs1[i](arr); minTime = sMin(minTime,(sInt) (sGetTimeUS() - start)); } VerifySorted(&arr[0],arr.GetCount()); sPrintF(L"%10d ",minTime); } sPrint(L"\n"); }
static void TestSequence2(const sChar *desc,sArrayRange<FakeVertex> &seq) { static const sInt nAttempts = 3; sStaticArray<FakeVertex> arr(seq.GetCount()); sPrintF(L"%-12s ",desc); for(sInt i=0; i<sCOUNTOF(sortFuncs2); i++) { // report minimum runtime over nAttempts runs sInt minTime = 0x7fffffff; for(sInt j=0; j<nAttempts; j++) { arr.Clear(); sCopyMem(arr.AddMany(seq.GetCount()),&seq[0],seq.GetCount()*sizeof(FakeVertex)); ThrashCache(); sU64 start = sGetTimeUS(); sortFuncs2[i](arr); minTime = sMin(minTime,(sInt) (sGetTimeUS() - start)); // verify that the sorted sequence is nondecreasing for(sInt i=1; i<arr.GetCount(); i++) sVERIFY(!(arr[i] < arr[i-1])); } sPrintF(L"%10d ",minTime); } sPrint(L"\n"); }
/* ** setPosition ** Sets the position of the multiScope window. */ void ofxMultiScope::setPosition(ofPoint min, ofPoint max) { _min = min; _max = max; for (int i=0; i<_numScopes; i++) { ofPoint sMin(min.x, min.y + i*(max.y - min.y)/_numScopes); ofPoint sMax(max.x, min.y + (i+1)*(max.y - min.y)/_numScopes); scopes.at(i).setPosition(sMin, sMax); } }
void MandelInfo::DoBatch(sInt b) { for(sInt y=0;y<LinesPerBatch;y++) { sInt yy = (b*LinesPerBatch+y); sU32 *p = yy*Pitch + Data; for(sInt x=0;x<SizeX;x++) { sU8 c = sMin(255,mandel(px+sx*x/SizeX,py+sy*yy/SizeY,255)); p[x] = (c<<0)|(c<<8)|(c<<16)|0xff000000; } } }
/* ** ofxMultiScope */ ofxMultiScope::ofxMultiScope(int numScopes, ofPoint min, ofPoint max, ofTrueTypeFont legendFont, int legendWidth, ofColor outlineColor, ofColor zeroLineColor, ofColor backgroundColor) { _min = min; _max = max; _numScopes = numScopes; scopes.resize(_numScopes); for (int i=0; i<_numScopes; i++) { ofPoint sMin(_min.x, _min.y + i*(_max.y - _min.y)/_numScopes); ofPoint sMax(_max.x, _min.y + (i+1)*(_max.y - _min.y)/_numScopes); scopes.at(i) = ofxOscilloscope(sMin, sMax, legendFont, legendWidth, outlineColor, zeroLineColor); } }
/* ** ofxMultiScope */ ofxMultiScope::ofxMultiScope(int numScopes, ofRectangle scopeArea, ofTrueTypeFont legendFont, int legendWidth, ofColor outlineColor, ofColor zeroLineColor, ofColor backgroundColor) { _min = scopeArea.getTopLeft(); _max = scopeArea.getBottomRight(); _numScopes = numScopes; scopes.resize(_numScopes); for (int i=0; i<_numScopes; i++) { ofPoint sMin(_min.x, _min.y + i*(_max.y - _min.y)/_numScopes); ofPoint sMax(_max.x, _min.y + (i+1)*(_max.y - _min.y)/_numScopes); scopes.at(i) = ofxOscilloscope(sMin, sMax, legendFont, legendWidth, outlineColor, zeroLineColor); } }
sF32 Wz4PDFAdd::GetDistance(const sVector31 &p) { if (Array.GetCount()) { sF32 d=Array[0]->GetDistance(p); for (sInt i=1;i<Array.GetCount();i++) { sF32 t=Array[i]->GetDistance(p); d = sMin(t,d); } return d; } else return 0; }
void sTextControl::DelSel() { sInt s0,s1,len; if(SelMode) { s0 = sMin(SelPos,Cursor); s1 = sMax(SelPos,Cursor); len = s1-s0; if(len>0) { Engine(s0,len,0); Cursor = s0; SelMode = 0; } } }
void SetCapacity(sPtr n) { T *newfirst = (T *) new uint8[sizeof(T)*n]; T *stop = sMin(Last,First+n); T *newlast = stop - First + newfirst; T *s = First; T *d = newfirst; while(s<stop) *d++ = *s++; while(s<Last) s->~T(); delete[] (uint8 *) First; First = newfirst; Last = newlast; End = newfirst + n; }
void sBasicPainter::Print(sInt /*fontid*/,sF32 x,sF32 y,sU32 col,const sChar *text,sInt len,sF32 zoom) { sVertexSingle *vp; if(len==-1) len = sGetStringLen(text); if(!len) return; #if sCONFIG_QUADRICS Geo->BeginQuad((void **)&vp,len); #else vp = Vertices + Used*4; len = sMin(len,Alloc-Used); Used += len; #endif for(sInt i=0;i<len;i++) { sInt c = text[i]; sInt u = (c&15)*8; sInt v = (c/16)*8; #if sRENDERER==sRENDER_DX9 || sRENDERER==sRENDER_DX11 sF32 uvo = UVOffset; sF32 xyo = XYOffset; #else sF32 uvo = 0.0f; sF32 xyo = 0.0f; #endif sFRect r(x+xyo,y+xyo,x+xyo+6*zoom,y+xyo+8*zoom); sFRect uv((u+uvo)/128.0f,(v+uvo)/128.0f,(u+6+uvo)/128.0f,(v+8+uvo)/128.0f); vp[0].Init(r.x0,r.y0,0,col,uv.x0,uv.y0); vp[1].Init(r.x1,r.y0,0,col,uv.x1,uv.y0); vp[2].Init(r.x1,r.y1,0,col,uv.x1,uv.y1); vp[3].Init(r.x0,r.y1,0,col,uv.x0,uv.y1); vp+=4; x+=6*zoom; } #if sCONFIG_QUADRICS Geo->EndQuad(); #endif }
sF32 Wz4PDFMerge::GetDistance(const sVector31 &p) { sF32 d1=Obj1->GetDistance(p); sF32 d2=Obj2->GetDistance(p); sF32 d; switch(Type) { case 5 : if (d1<0) d1=0; if (d2<0) d2=0; d=d1*(1.0f-Factor)+d2*Factor; break; case 4 : if (d1<d2) { d=d1*(1.0f-Factor)+d2*Factor; } else { d=d2*(1.0f-Factor)+d1*Factor; } break; case 3 : d=d1*(1.0f-Factor)+d2*Factor; break; case 2 : d1=-d1; d = sMax(d1,d2); break; case 1 : d = sMax(d1,d2); break; default : d = sMin(d1,d2); break; } return d; }
void sMultipleChoiceDialog::OnPaint2D() { sRect t,b,r,l; Item *item; sInt h; sFont2D *font = sGui->PropFont; sClipPush(); t = b = Client; t.x1 = b.x0 = Client.x0 + Client.SizeX()*2/3; t.Extend(-4); font->SetColor(sGC_TEXT,sGC_BACK); font->Print(sF2P_OPAQUE|sF2P_LEFT|sF2P_TOP|sF2P_MULTILINE,t,Text); sClipExclude(t); b.Extend(-4); h = font->GetHeight()*2; sFORALL(Items,item) { r = b; r.y0 = b.y0 + (_i+0)*h; r.y1 = b.y0 + (_i+1)*h-4; item->Rect = r; sGui->PaintButtonBorder(r,_i==PressedItem && PressedOk); l = r; l.x1 = r.x0 = sMin(r.x1,r.x0+font->GetWidth(L" ")+font->GetWidth(item->Text)); font->SetColor(sGC_TEXT,sGC_BUTTON); font->Print(sF2P_OPAQUE|sF2P_SPACE|sF2P_LEFT,l,item->Text); sString<64> buffer; sButtonControl::MakeShortcut(buffer,item->Shortcut); font->Print(sF2P_OPAQUE|sF2P_SPACE|sF2P_RIGHT,r,buffer); font->SetColor(sGC_TEXT,sGC_BACK); sClipExclude(item->Rect); }
void Spectogram(sImage *out,sInt width,sInt fftSize) { sInt fftHalf = fftSize/2; sInt overlap = fftHalf; sF32 *windowFunction = new sF32[fftSize]; for(sInt i=0;i<fftSize;i++) windowFunction[i] = 0.5f * (1.0f + sFCos((i - fftHalf) * sPIF / fftHalf)); out->Init(width,fftHalf); sComplex *fftVec = new sComplex[fftSize]; sU32 *ptr = out->Data; for(sInt i=0;i<width;i++) { // read fft inputs sInt startSmp = i*overlap; for(sInt j=0;j<fftSize;j++) { sInt smp = sMin(startSmp+j,App->MusicSize-1); sF32 sample = 0.5f * (App->MusicData[smp*2+0] + App->MusicData[smp*2+1]) / 32768.0f; fftVec[j] = sample * windowFunction[j]; } // calc fft sFFT(fftVec,fftSize,sFALSE); // gen output for(sInt j=0;j<fftHalf;j++) { sF32 magn = sFSqrt(fftVec[j].r*fftVec[j].r + fftVec[j].i*fftVec[j].i); sU32 col = 0xff000000 + sClamp<sInt>(magn*255,0,255)*0x010101; ptr[(fftHalf-1-j)*width+i] = col; } } delete[] fftVec; delete[] windowFunction; }
void RMSImage(sImage *out,sInt width,sInt height,sInt chunkSize) { out->Init(width,height); sU32 *ptr = out->Data; for(sInt i=0;i<width;i++) { sInt startSmp = i*chunkSize; sInt endSmp = sMin((i+1)*chunkSize,App->MusicSize); sF32 sum = 0.0f; for(sInt j=startSmp;j<endSmp;j++) { sF32 sample = 0.5f * (App->MusicData[j*2+0] + App->MusicData[j*2+1]) / 32768.0f; sum += sample*sample; } sF32 intens = (endSmp>startSmp) ? sFSqrt(sum / (endSmp-startSmp)) : 0.0f; sU32 col = 0xff000000 + sClamp<sInt>(intens*255,0,255)*0x010101; for(sInt j=0;j<height;j++) ptr[j*width+i] = col; } }
bool DumpMemory() { // whats up? if(Active==0) return 0; if(Active==2) return 0; if(LeakCount==0) { sLog("sys","no memory leaks detected\n\n"); return 1; } if(LeakCount<0) { sDPrint("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); sDPrint("negative number of leaks - this can't be\n"); return 0; } // make linear array of all leaks sArray<Leak> Leaks; int count = LeakCount; Leak *data = (Leak *) sAllocMemSystem(count*sizeof(Leak),4,0); Leaks.OverrideStorage(data,count); for(int i=0;i<HashSize;i++) { Leak *n = Hash[i]; while(n) { Leaks.Add(*n); n = n->Next; } } sASSERT(count==Leaks.GetCount()); Leaks.QuickSort(cmp()); // merge { sptr count = Leaks.GetCount(); Leak *data = Leaks.GetData(); int d = 0; int s = 0; while(s<count) { if(d>0 && data[d-1].Line==data[s].Line && sCmpString(data[d-1].File,data[s].File)==0) { data[d-1].Count++; data[d-1].Size += data[s].Size; data[d-1].Id = sMin(data[d].Id,data[s].Id); s++; } else { data[d++] = data[s++]; } } Leaks.SetSize(d); } // sort for output Leaks.QuickSort(cmp2()); // output (combined) sDPrint("/****************************************************************************/\n"); sDPrint("/*** ***/\n"); sDPrint("/*** memory leaks! ***/\n"); sDPrint("/*** ***/\n"); sDPrint("/****************************************************************************/\n"); sDPrint("\n"); sDPrintF("file(line): size count id\n"); sDPrint("\n"); for(auto &n : Leaks) { sString<256> buffer; buffer.PrintF("%s(%d):",n.File,n.Line); sDPrintF("%-60s%6K %5d %5d\n",buffer,n.Size,n.Count,n.Id); } sDPrint("\n"); sDPrint("/****************************************************************************/\n\n"); // done Leaks.OverrideStorage(0,0); sFreeMemSystem(data); return 0; }
static sBool sRectsIntersect(const sRect &a,const sRect &b) { return sMax(a.x0,b.x0) < sMin(a.x1,b.x1) && sMax(a.y0,b.y0) < sMin(a.y1,b.y1); }
void BestPackerFrontEnd::DoPack(PackerCallback cb) { struct Token { sU32 DecodeSize; sU32 Pos; sF64 CodeSize; }; Token *tk,*tokens; sU32 *links; sU32 *head,i,key,ptr,depth,bestOff,bestLen,count,maxs; sU32 lastBestLen,lastBestOff; sF32 sz; const sU8 *src1,*src2; sU8 tick; tokens = new Token[SourceSize+1]; sSetMem(tokens,0,sizeof(Token)*(SourceSize+1)); // prepare match tables head = new sU32[65536]; links = new sU32[SourceSize]; sSetMem(head,0xff,sizeof(sU32)*65536); for(i=0;i<SourceSize-1;i++) { key = *(sU16 *) (Source + i); links[i] = head[key]; head[key] = i; } links[SourceSize-1] = ~0U; delete[] head; // pathfinding loop tick = 0; lastBestLen = 0; lastBestOff = 0; for(i=SourceSize-1;i!=~0U;i--) { tk = tokens+i; // start with literal tk->DecodeSize = 1; tk->Pos = i; tk->CodeSize = BackEnd->AvgLiteralLen + tk[1].CodeSize; ptr = links[i]; depth = 0; if(lastBestLen && i>=lastBestOff && Source[i] == Source[i-lastBestOff]) { // try to append to match from last iteration if possible sz = BackEnd->MatchLen(lastBestOff,lastBestLen+1); if(sz+tk[lastBestLen+1].CodeSize < tk->CodeSize) { bestLen = lastBestLen+1; bestOff = lastBestOff; tk->DecodeSize = bestLen; tk->Pos = bestOff; tk->CodeSize = sz + tk[bestLen].CodeSize; } } else { bestOff = 0; bestLen = 0; } maxs = SourceSize-i; if(!++tick && cb) cb(sMin(maxs,SourceSize-1),SourceSize,0); while(ptr != ~0U) { src1 = Source + i; src2 = Source + ptr; count = 0; if(src1[bestLen] == src2[bestLen]) { while(count+3<maxs && *(sU32 *) (src1+count) == *(sU32 *) (src2+count)) count+=4; while(count<maxs && src1[count]==src2[count]) count++; if(count>1) { sz = BackEnd->MatchLen(i-ptr,count); if(sz+tk[count].CodeSize < tk->CodeSize) { bestLen = count; bestOff = i-ptr; tk->DecodeSize = bestLen; tk->Pos = bestOff; tk->CodeSize = sz + tk[bestLen].CodeSize; } } } if(++depth == 2048) break; ptr = links[ptr]; } lastBestLen = bestLen; lastBestOff = bestOff; } // encoding loop for(i=SourcePtr;i<SourceSize;i+=tokens[i].DecodeSize) { tk = tokens+i; // try things we can't during pathfinding: actual literal size... sz = BackEnd->LiteralLen(i,1); if(sz+tk[1].CodeSize < tk->CodeSize) { tk->DecodeSize = 1; tk->CodeSize = sz + tk[1].CodeSize; } // and previous match references for(sInt j=0;j<BackEnd->nPrevOffsets;j++) { if(BackEnd->PrevOffset[j]) { count = 0; src1 = Source + i; src2 = Source + i - BackEnd->PrevOffset[j]; while(i+count<SourceSize && src1[count]==src2[count]) count++; if(count > 1) { sz = BackEnd->MatchLen(BackEnd->PrevOffset[j],count); if(sz+tk[count].CodeSize < tk->CodeSize) { tk->DecodeSize = count; tk->Pos = BackEnd->PrevOffset[j]; tk->CodeSize = sz + tk[count].CodeSize; } } } } if(tk->DecodeSize == 1) BackEnd->EncodeLiteral(i,tk->DecodeSize); else BackEnd->EncodeMatch(tk->Pos,tk->DecodeSize); } delete[] tokens; }
void RNFR067_IsoSplash::MarchTask(sStsThread *thread,sInt start,sInt count) { sInt id = thread ? thread->GetIndex() : 0; sSchedMon->Begin(id,0xff8080); const sInt s1 = CellSize+1; const sInt s2 = CellSize+2; const sInt s3 = CellSize+3; for(sInt ii=start;ii<start+count;ii++) { IsoNode *node = &Nodes[ii]; sF32 pots[s3][s3][s3]; sVector31 p0 = node->Min; sVector31 pp; // calculate some coefficients sF32 pd = (node->Max.x-node->Min.x)/CellSize; p0.x -= pd; p0.y -= pd; p0.z -= pd; sMatrix34 mat[s3]; if(RubberEnable) { for(sInt y=0;y<s3;y++) { sF32 py = p0.y+pd*y; mat[y].EulerXYZ((Para.Rot.x+Para.Rubber.x*py)*sPI2F, (Para.Rot.y+Para.Rubber.y*py)*sPI2F, (Para.Rot.z+Para.Rubber.z*py)*sPI2F); } } else { mat[0].EulerXYZ(Para.Rot.x*sPI2F,Para.Rot.y*sPI2F,Para.Rot.z*sPI2F); for(sInt y=1;y<s3;y++) mat[y] = mat[0]; } // check some points sInt testpoints[9][3] = { { 5,5,5 }, { 1,1,1 }, { 1,1,9 }, { 1,9,1 }, { 1,9,9 }, { 9,1,1 }, { 9,1,9 }, { 9,9,1 }, { 9,9,9 }, }; sF32 pmin = 1000; sF32 pmax = -1000; for(sInt i=0;i<9;i++) { pp.x = p0.x+pd*testpoints[i][0]; pp.y = p0.y+pd*testpoints[i][1]; pp.z = p0.z+pd*testpoints[i][2]; sF32 f = func(pp ,testpoints[i][0]+node->px ,testpoints[i][1]+node->py ,testpoints[i][2]+node->pz); pmin = sMin(pmin,f); pmax = sMax(pmax,f); } if(!(pmax>-Para.QuickOutSaveGuard && pmin<Para.QuickOutSaveGuard)) continue; // generate volume pmin = 1000; pmax = -1000; for(sInt z=0;z<s3;z++) { for(sInt y=0;y<s3;y++) { for(sInt x=0;x<s3;x++) { pp.x = p0.x+pd*x; pp.y = p0.y+pd*y; pp.z = p0.z+pd*z; sF32 f = func(pp,x+node->px ,y+node->py ,z+node->pz); pots[z][y][x] = f; pmin = sMin(pmin,f); pmax = sMax(pmax,f); } } } if(!(pmax>0 && pmin<0)) continue; // generate normals MCPotField pot[s1+1][s1][s1]; sVector30 n; for(sInt z=1;z<s2;z++) { for(sInt y=1;y<s2;y++) { for(sInt x=1;x<s2;x++) { sF32 w = pots[z][y][x]; n.x = pots[z][y][x+1] - pots[z][y][x-1]; n.y = pots[z][y+1][x] - pots[z][y-1][x]; n.z = pots[z+1][y][x] - pots[z-1][y][x]; sF32 e = n.x*n.x + n.y*n.y + n.z*n.z; if(e>1e-24f) { e=sFRSqrt(e); n.x = e*n.x; n.y = e*n.y; n.z = e*n.z; } else { n.Init(0,0,0); } pot[z-1][y-1][x-1].x = -n.x; pot[z-1][y-1][x-1].y = -n.y; pot[z-1][y-1][x-1].z = -n.z; pot[z-1][y-1][x-1].w = w; } } } // marching cubes MC.March(3,&pot[0][0][0],pd*Para.GridSize*0.5f,sVector31(sVector30(node->Min)*(Para.GridSize*0.5f)),id); } sSchedMon->End(id); }
void sChoiceControl::InitChoices(const sChar *&s,sInt *val) { sInt id = 0; ChoiceInfo *ci; sInt min=0; sInt max=0; sInt len; sBool fullmask = 0; Choices.Clear(); ValueMask = 0; ValueShift = 0; if(*s=='#') { s++; fullmask = 1; } if(*s=='*') { s++; sScanInt(s,ValueShift); } for(;;) { while(*s=='|') { s++; id++; } if(*s==':' || *s==0) break; if(sIsDigit(*s) || (*s=='-' && sIsDigit(s[1])) || (*s=='+' && sIsDigit(s[1]))) sScanInt(s,id); if(*s==' ') s++; len = 0; while(s[len]!='|' && s[len]!=':' && s[len]!=0) len++; ci = Choices.AddMany(1); ci->Label = s; ci->Length = len; ci->Value = id; min = sMin(min,id); max = sMax(max,id); s+=len; } ValueMask = 1; while(ValueMask<max) ValueMask = ValueMask*2+1; if (min<0) ValueMask = ~0; ValueMask <<= ValueShift; if(fullmask) ValueMask = ~0; if(val) { Values.Clear(); AddMultiChoice(val); ClearNotify(); AddNotify(val,sizeof(sInt)); Style = Choices.GetCount()==2 ? sCBS_CYCLE : sCBS_DROPDOWN; } else { Style |= sCBS_DROPDOWN; } }
sBool sTextControl::OnCommand(sU32 cmd) { sInt s0,s1,len; sDiskItem *di; sChar buffer[sDI_PATHSIZE]; sChar *t; s0 = sMin(SelPos,Cursor); s1 = sMax(SelPos,Cursor); len = s1-s0; switch(cmd) { case sTCC_CUT: if(SelMode && s0!=s1) { sGui->ClipboardClear(); sGui->ClipboardAddText(Text+s0,len); Engine(s0,len,0); Post(DoneCmd); SelMode = 0; Cursor = s0; } return sTRUE; case sTCC_COPY: if(SelMode && s0!=s1) { sGui->ClipboardClear(); sGui->ClipboardAddText(Text+s0,len); SelMode = 0; } return sTRUE; case sTCC_PASTE: t = sGui->ClipboardFindText(); if(t && t[0]) { Engine(Cursor,sGetStringLen(t),t); Cursor+=sGetStringLen(t); Post(DoneCmd); } return sTRUE; case sTCC_BLOCK: if(SelMode==0) { SelMode = 2; SelPos = Cursor; } else { SelMode = 0; } return sTRUE; case 3: // Cancel File Requester if(File) { File->Parent->RemChild(File); File = 0; } return sTRUE; case sTCC_OPEN: if(!File) { File = new sFileWindow; File->AddTitle("Open File"); sGui->AddApp(File); } sGui->SetFocus(File); File->OkCmd = 4; File->CancelCmd = 3; File->SendTo = this; Modal = File; File->SetPath(PathName); return sTRUE; case 4: if(File) { File->GetPath(buffer,sizeof(buffer)); OnCommand(3); if(!LoadFile(buffer)) { SetText(""); (new sDialogWindow)->InitOk(this,"Open File","Load failed",0); } } return sTRUE; case sTCC_CLEAR: SetText(""); return sTRUE; case sTCC_SAVEAS: if(!File) { File = new sFileWindow; File->AddTitle("Open File"); sGui->AddApp(File); } sGui->SetFocus(File); File->OkCmd = 5; File->CancelCmd = 3; File->SendTo = this; Modal = File; File->SetPath(PathName); return sTRUE; case 5: if(File) { File->GetPath(PathName,sizeof(PathName)); OnCommand(3); OnCommand(sTCC_SAVE); } return sTRUE; case sTCC_SAVE: di = sDiskRoot->Find(PathName,sDIF_CREATE); if(di) { len = sGetStringLen(Text); if(di->SetBinary(sDIA_DATA,(sU8 *)Text,len)) { Post(CursorCmd); Changed = 0; } else { (new sDialogWindow)->InitOk(this,"Save File","Save failed",0); } } return sTRUE; default: return sFALSE; } }
void __stdcall Exec_Scene_Walk(KOp *op,KEnvironment *kenv, sU32 Flags,sInt FootCount,sF32 StepTresh,sF32 RunLowTresh,sF32 RunHighTresh, sInt2 fg,sF322 sl,sF322 ss,sF322 sn, sF323 l0,sF323 l1,sF323 l2,sF323 l3,sF323 l4,sF323 l5,sF323 l6,sF323 l7, sF32 scanup,sF32 scandown, KSpline *stepspline) { sMatrix mat;//,save; // local vars sMatrix dir; // desired orientation of walker sVector savevar[8],savetime; sVector v,sum,foot[8],spline[8],stepdir; // sVector plane; sInt i,j; sInt bestleg; sInt time; sF32 dist,f,t; sInt changestate; // KKriegerCellAdd *cell; sZONE(ExecWalk); // copy of instance-vars sInt State; sInt LastLeg; sInt NextLeg; // parameters sInt FootGroup[2]; // groups of feet. sF32 StepLength[2]; // max. length of a step sInt StepSpeed[2]; // duration of a step in ms. sInt StepNext[2]; // when to start the next step in ms. steps may overlap // init parameters FootGroup[0] = fg.x; FootGroup[1] = fg.y; StepLength[0] = sl.x; StepLength[1] = sl.y; StepSpeed[0] = sFtol(ss.x*1000); StepSpeed[1] = sFtol(ss.y*1000); StepNext[0] = sMin(sFtol(sn.x*1000),StepSpeed[0]); StepNext[1] = sMin(sFtol(sn.y*1000),StepSpeed[1]); // init instance storage sMatrix &matrix = kenv->ExecStack.Top(); mem = kenv->GetInst<WalkMem>(op); if(mem->Reset || (Flags&0x100) || kenv->TimeReset) { // cell = 0; // if(Flags&2) // cell = kenv->Game->FindCell(matrix.l); sum.Init(); mem->FootCenter.Init(); mem->InitSteps = FootCount*2; for(i=0;i<FootCount;i++) { mem->FootDelta[i].Init((&l0)[i].x,(&l0)[i].y,(&l0)[i].z,0); v.Add3(matrix.l,mem->FootDelta[i]); v.w = 0; mem->FootOld[i] = mem->FootNew[i] = v; mem->StepTime[i] = StepSpeed[0]; // mem->FootPart[i].Init(v,sum,cell); mem->FootCenter.x += mem->FootDelta[i].x/FootCount; mem->FootCenter.z += mem->FootDelta[i].z/FootCount; } // mem->FootPart[FootCount-1].EndMarker = 1; // mem->BodyPart.Init(matrix.l,sum,cell); // mem->BodyPart.EndMarker = 1; mem->LastTime = kenv->CurrentTime; mem->NewPos = matrix.l; mem->State = 0; mem->LastLeg = 0; for(i=0;i<FootCount;i++) mem->FootDelta[i].Sub3(mem->FootCenter); } State = mem->State; LastLeg = mem->LastLeg; NextLeg = mem->NextLeg; // fake for animation #if !sINTRO if(Flags & 0x30) { sInt k; State = ((Flags&0x30)==0x20); j = FootGroup[State]; f = (StepTresh+RunLowTresh)/2; if(j) f = (RunLowTresh+RunHighTresh)/2; f = f/j; if(Flags&0x40) f *= 2; time = kenv->CurrentTime % (StepNext[State]*j); k = kenv->CurrentTime / (StepNext[State]*j); for(i=0;i<FootCount;i++) { mem->StepTime[i] = time - (StepNext[State]*(i%j)); if(Flags&0x80) mem->FootOld[i].Init(0,0,f*(i%j-(time*1.0f/StepNext[State])-(j-1)*0.5f)); else mem->FootOld[i].Init(0,0,f*(k*j+(i%j))); mem->FootOld[i].Add3(mem->FootDelta[i]); mem->FootNew[i] = mem->FootOld[i]; mem->FootNew[i].z += f*j; if(mem->StepTime[i]<StepSpeed[State]-StepNext[State]*j) { mem->StepTime[i] += StepNext[State]*j; mem->FootOld[i].z -= f*j; mem->FootNew[i].z -= f*j; } if(mem->StepTime[i]<0) { mem->FootNew[i] = mem->FootOld[i]; mem->StepTime[i] = StepSpeed[State]; } if(mem->StepTime[i]>StepSpeed[State]) mem->StepTime[i] = StepSpeed[State]; } } #endif // animate sum.Init(); f = 0; for(i=0;i<FootCount;i++) { t = sRange(1.0f*mem->StepTime[i]/StepSpeed[State],1.0f,0.0f); if(i<FootGroup[State]) { f += t; } #pragma lekktor(on) if(stepspline) { stepspline->Eval((t+State)*0.5f,spline[i]); if(mem->FootDelta[i].x<0) spline[i].x=-spline[i].x; if(mem->FootDelta[i].z<0) spline[i].z=-spline[i].z; spline[i].w = spline[i].w-State; } else { spline[i].x = 0; spline[i].y = sFSin(t*sPI)*0.25f; spline[i].z = 0; spline[i].w = t; } #pragma lekktor(off) foot[i].Lin3(mem->FootOld[i],mem->FootNew[i],spline[i].w); foot[i].w = 1.0f; /* if(Flags&0x02) { foot[i].y += spline[i].y; mem->FootPart[i].Control(foot[i]); foot[i].y -= spline[i].y; } */ sum.Add3(foot[i]); } sum.Scale3(1.0f/FootCount); mat.i.Init(0,0,0,0); mat.j.Init(0,0,0,0); // ryg 040820 mat.k.Init(0,0,0,0); mat.l.Init(sum.x,sum.y,sum.z,1); for(i=0;i<FootCount;i++) { v.Sub3(foot[i],sum); mat.i.AddScale3(v,mem->FootDelta[i].x); mat.j.AddScale3(v,mem->FootDelta[i].y); mat.k.AddScale3(v,mem->FootDelta[i].z); } #pragma lekktor(on) switch((Flags>>2)&3) { case 0: // straight, copy from input mat.i = matrix.i; mat.j = matrix.j; mat.k = matrix.k; break; case 2: // use xy mat.i.Unit3(); mat.j.Init(0,1,0,0); mat.k.Cross4(mat.i,mat.j); mat.k.Unit3(); mat.j.Cross4(mat.k,mat.i); mat.j.Unit3(); break; case 1: // use y mat.k = matrix.k; case 3: // use xz mat.k.Unit3(); mat.j.Cross4(mat.k,mat.i); mat.j.Unit3(); mat.i.Cross4(mat.j,mat.k); mat.i.Unit3(); break; } #pragma lekktor(off) t = (f+LastLeg)/FootGroup[State]; if(t>=2.0f) t-=2.0f; if(t>=1.0f) t-=1.0f; t = (t+State)*0.5f; savetime = kenv->Var[KV_LEG_TIMES]; kenv->Var[KV_LEG_TIMES].Init(t,0,0,0); // advance time = kenv->CurrentTime-mem->LastTime; mem->LastTime = kenv->CurrentTime; if(time<0) time = 0; dir = matrix; if(mem->DeviationFlag>0) { dir.l.Add3(mat.l,mem->Deviation); } /* if(mem->BodyPart.Cell) { dir.l.y += 0.5f; if(kenv->CurrentEvent && kenv->CurrentEvent->Monster) mem->BodyPart.SkipCell = &kenv->CurrentEvent->Monster->Cell; mem->BodyPart.Control(dir.l); dir.l.y -= 0.5f; } */ dir.k.y = 0; dir.k.Unit3(); dir.j.Init(0,1,0,0); dir.i.Cross4(dir.j,dir.k); for(i=0;i<FootCount;i++) { if(mem->StepTime[i]<StepSpeed[State]) mem->StepTime[i] += time; } // find distance dist = 0; stepdir.Init(); NextLeg = (LastLeg+1)%FootGroup[State]; bestleg = NextLeg; for(i=0;i<FootCount;i++) { v.Rotate34(dir,mem->FootDelta[i]); v.Sub3(foot[i]); v.y = 0; f = v.Abs3(); if(f>dist && mem->StepTime[i]>=StepSpeed[State]) { dist = f; stepdir = v; bestleg = i; } savevar[i] = kenv->Var[KV_LEG_L0+i]; v.Rotate3(dir,spline[i]); kenv->Var[KV_LEG_L0+i].Add3(foot[i],v); kenv->Var[KV_LEG_L0+i].w = spline[i].w; } // change walking/running changestate = 1; for(i=0;i<FootCount;i++) if(mem->StepTime[i]<StepSpeed[State]) changestate = 0; if((State==0 && dist>RunHighTresh) || (State==1 && dist<RunLowTresh)) changestate +=2; // changestate = 0 -> in animation -> // changestate = 1 -> animation done. -> issue bestleg when idle // changestate = 2 -> in animation, change state -> don't issue new steps // changestate = 3 -> animation done, change state -> change state really // sDPrintF("%08x:state %d change %d dist %f | %4d %4d %4d %4d %4d %4d\n",mem,State,changestate,dist,mem->StepTime[0],mem->StepTime[1],mem->StepTime[2],mem->StepTime[3],mem->StepTime[4],mem->StepTime[5]); if(changestate==3) { if((State==0 && dist>RunHighTresh) || (State==1 && dist<RunLowTresh)) { State=1-State; changestate = 0; LastLeg = LastLeg%FootGroup[State]; for(i=0;i<FootCount;i++) mem->StepTime[i]=StepSpeed[State]; NextLeg = bestleg%FootGroup[State]; } } bestleg = bestleg%FootGroup[State]; if(mem->Idle && changestate==1) NextLeg = bestleg; // do the next step mem->Idle = 0; if(changestate!=2 && mem->StepTime[LastLeg]>=StepNext[State] && mem->StepTime[NextLeg]>=StepSpeed[State]) { if(mem->InitSteps>0) { mem->InitSteps--; dist = 1024; } if(mem->DeviationFlag>0) mem->DeviationFlag--; if(dist>StepTresh) { v.Sub3(dir.l,mat.l); f = v.Abs3(); if((Flags & 1) && mem->InitSteps==0) NextLeg = bestleg; if(f>StepLength[State]) { mem->NewPos = mat.l; mem->NewPos.AddScale3(v,StepLength[State]/f); } else { mem->NewPos = dir.l; } // mem->NewPos.y = 0; dir.l = mem->NewPos; j = mem->StepTime[LastLeg]-StepNext[State]; for(i=NextLeg;i<FootCount;i+=FootGroup[State]) { mem->FootOld[i] = foot[i];//mem->FootNew[i]; // sDPrintF("soll: %06.3f %06.3f %06.3f --\n ist: %06.3f %06.3f %06.3f\n",mem->FootOld[i].x,mem->FootOld[i].y,mem->FootOld[i].z,dir.l.x,dir.l.y,dir.l.z); v = mem->FootDelta[i]; v.y = 0; v.Rotate34(dir); /* if(mem->FootPart[i].Cell) { KKriegerCellAdd *cell; sVector p0,p1; mem->FootNew[i] = v; // do the step in any case... mem->StepTime[i] = j; kenv->Game->CollisionForMonsterMode = 1; // and then find a better point-- p0 = v; p0.y += scanup; cell = kenv->Game->FindCell(p0); if(cell) { p1 = v; p1.y -= scandown; if(kenv->Game->FindFirstIntersect(p0,p1,cell,&plane)) { if(plane.y>0.75 && p1.y<p0.y) { mem->FootNew[i] = p1; mem->StepTime[i] = j; } } } kenv->Game->CollisionForMonsterMode = 0; } else*/ { mem->FootNew[i] = v; mem->StepTime[i] = j; } } LastLeg = NextLeg; } else { mem->Idle = 1; } } // paint & cleanup /* if(mem->BodyPart.Cell) { // kenv->Game->AddPart(&mem->FootPart[0]); kenv->Game->AddPart(&mem->BodyPart); } */ kenv->ExecStack.Push(mat); //save = kenv->ExecMatrix; //kenv->ExecMatrix = mat; op->ExecInputs(kenv); kenv->ExecStack.Pop(); //kenv->ExecMatrix = save; mem->State = State; mem->LastLeg = LastLeg; mem->NextLeg = NextLeg; for(i=0;i<FootCount;i++) { kenv->Var[KV_LEG_L0+i] = savevar[i]; } kenv->Var[KV_LEG_TIMES] = savetime; // if(kenv->CurrentEvent) // kenv->CurrentEvent->ReturnMatrix = mat; }
void sTextControl::OnPaint() { sChar *p; sInt i,x,y,h,xs; sInt pos; sRect r; sInt font; sInt s0,s1; if(RecalcSize) // usefull for Logwindow { RecalcSize = 0; OnCalcSize(); } x = Client.x0+2; y = Client.y0+2; font = sGui->FixedFont; h = sPainter->GetHeight(font); p = Text; pos = 0; s0 = s1 = 0; if(SelMode) { s0 = sMin(Cursor,SelPos); s1 = sMax(Cursor,SelPos); } r.y0 = y-2; r.y1 = y; r.x0 = Client.x0; r.x1 = Client.x1; sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_BACK]); for(;;) { i = 0; while(p[i]!=0 && p[i]!='\n') i++; r.y0 = y; r.y1 = y+h; r.x0 = Client.x0; r.x1 = Client.x1; if(sGui->CurrentClip.Hit(r)) { sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_BACK]); if(Cursor>=pos && Cursor<=pos+i) { r.x0 = x+sPainter->GetWidth(font,p,Cursor-pos); if(Overwrite) { if(Cursor==pos+i) r.x1 = x+sPainter->GetWidth(font," "); else r.x1 = x+sPainter->GetWidth(font,p,Cursor-pos+1); sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_SELBACK]); } else { r.x1 = r.x0+1; r.x0--; sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_TEXT]); } } if(SelMode && s0<=pos+i && s1>=pos) { if(s0<=pos) r.x0 = x; else r.x0 = x+sPainter->GetWidth(font,p,s0-pos); if(s1>pos+i) r.x1 = x+sPainter->GetWidth(font,p,i)+sPainter->GetWidth(font," "); else r.x1 = x+sPainter->GetWidth(font,p,s1-pos); sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_SELBACK]); } sPainter->Print(font,x,y,p,sGui->Palette[sGC_TEXT],i); } xs = sPainter->GetWidth(font,p,i)+4+sPainter->GetWidth(font," "); y+=h; p+=i; pos+=i; if(*p==0) break; if(*p=='\n') { p++; pos++; } } r.y0 = y; r.y1 = Client.y1; r.x0 = Client.x0; r.x1 = Client.x1; if(r.y0<r.y1) sPainter->Paint(sGui->FlatMat,r,sGui->Palette[sGC_BACK]); }
void sBSpline::LeastSquaresFit(const Sample *samples,sInt nSamples) { // The input dataset is assumed to be on [0,1) // Now do a least-squares fit via normal equations, that is solve // (A^T A) x = A^T b // for x. // // To do this, first compute the weights of the B-Spline at // sample points to determine A sInt deg = Degree,order = Degree + 1; sInt nKnots = Knots.Count; sF32 *A = new sF32[nSamples * order]; sInt *start = new sInt[nSamples]; for(sInt i=0; i<nSamples; i++) if(samples[i].Type == 0) // normal function value CalcBasis(samples[i].Time,start[i],A + i*order); else // derivative CalcBasisDeriv(samples[i].Time,start[i],A + i*order); // Next, calculate the matrix A^T A. This is always symmetrical and // positive semidefinite, and in this case also a banded matrix, so we // only need order * nKnots floats to store it sF32 *ATA = new sF32[nKnots * order]; for(sInt i=0; i<nKnots; i++) { // samples for knot i sInt start1 = lowerBound(start,i-deg,nSamples); sInt end1 = lowerBound(start,i+1,nSamples); for(sInt j=0; j<order; j++) { // samples for knot i+j-deg sInt start2 = lowerBound(start,i+j-2*deg,nSamples); sInt end2 = lowerBound(start,i+j-deg+1,nSamples); // calculate overlap sInt commonStart = sMax(start1,start2); sInt commonEnd = sMin(end1,end2); // perform summation sF64 sum = 0.0f; for(sInt k=commonStart; k<commonEnd; k++) { sF32 *pos = &A[k*order + i-start[k]]; sum += pos[0] * pos[j-deg]; } ATA[i*order+j] = sum; } } // Compute a LDL^T decomposition of A^T A (in-place) sF32 *scale = new sF32[nKnots]; for(sInt i=0; i<nKnots; i++) { // Solve for diagonal element sF64 d = ATA[i*order+deg]; for(sInt j=sMax(i-deg,0); j<i; j++) d -= sSquare(ATA[i*order+(j-i)+deg])*ATA[j*order+deg]; // Calculate inverse d, store back d = (sFAbs(d) > 1e-10f) ? d : 0.0f; sF64 id = d ? 1.0f / d : 0.0f; ATA[i*order+deg] = d; scale[i] = id; // Solve for rest for(sInt j=1; j<order; j++) { sInt row = i+j; if(row < nKnots) { sF64 sum = ATA[row*order+deg-j]; for(sInt k=sMax(row-deg,0); k<i; k++) sum -= ATA[row*order+(k-row)+deg] * ATA[i*order+(k-i)+deg] * ATA[k*order+deg]; ATA[row*order+deg-j] = id * sum; } } } // Now, actually solve the system. Anything before this only needs to be // done once per knot vector. // Compute A^T b for(sInt i=0; i<nKnots; i++) { sInt startw = lowerBound(start,i-deg,nSamples); sInt endw = lowerBound(start,i+1,nSamples); sF64 c = 0.0f; for(sInt j=startw; j<endw; j++) c += A[j*order + i-start[j]] * samples[j].Value; Values[i] = c; } // Solve Lx for(sInt i=0; i<nKnots; i++) { sF64 sum = Values[i]; for(sInt j=sMax(i-deg,0); j<i; j++) sum -= ATA[i*order+(j-i)+deg] * Values[j]; Values[i] = sum; } // Solve Dx for(sInt i=0; i<nKnots; i++) Values[i] *= scale[i]; // Solve L^Tx (backwards substitution) for(sInt i=nKnots-2; i>=0; i--) { sF64 sum = Values[i]; for(sInt j=i+1; j<sMin(i+order,nKnots); j++) sum -= ATA[j*order+(i-j)+deg] * Values[j]; Values[i] = sum; } // Cleanup delete[] A; delete[] start; delete[] ATA; delete[] scale; }
void sFont2D::PrintMarked(sInt flags,const sRect *rc,sInt x,sInt y,const sChar *text,sInt len,sPrintInfo *pi) { if(len==-1) len=sGetStringLen(text); sVERIFY(rc); sVERIFY(pi); sRect r(*rc); const sChar *ot = text; sInt ol = len; sInt ox = x; sBool nocull = 0; switch(pi->Mode) { case sPIM_PRINT: nocull = pi->CullRect.IsEmpty() || rc->IsInside(pi->CullRect); if(pi->SelectStart<len && pi->SelectEnd>0 && pi->SelectEnd>pi->SelectStart) { sInt i = pi->SelectStart; if(i>0) { r.x1 = x + GetWidth(text,i); PrintBasic(flags,&r,x,y,text,i); r.x0 = x = r.x1; len -= i; pi->SelectEnd -= i; pi->SelectStart -= i; text += i; } sU32 oldbackcolor=prv->BackColor; if (pi->SelectBackColor!=~0) prv->BackColor=BrushColor[pi->SelectBackColor]; else sSwap(prv->TextColor,prv->BackColor); i = sMin(pi->SelectEnd,len); r.x1 = x + GetWidth(text,i); if(nocull) PrintBasic(flags,&r,x,y,text,i); r.x0 = x = r.x1; len -= i; pi->SelectEnd -= i; pi->SelectStart -= i; text += i; if (pi->SelectBackColor!=~0) prv->BackColor=oldbackcolor; else sSwap(prv->TextColor,prv->BackColor); } if(nocull) { r.x1 = x + GetWidth(text,len); PrintBasic(flags,&r,x,y,text,len); if(flags & sF2P_OPAQUE) { r.x0 = x = r.x1; r.x1 = rc->x1; if(pi->HintLine && pi->HintLine>=r.x0 && pi->HintLine+2<=r.x1) { r.x1 = pi->HintLine; sRect2D(r,prv->BackPen); r.x0 = r.x1; r.x1 = r.x0+2; sRect2D(r,pi->HintLineColor); r.x0 = r.x1; r.x1 = rc->x1; } sRect2D(r,prv->BackPen); } } if(pi->CursorPos>=0 && pi->CursorPos<=ol && pi->Mode==sPIM_PRINT) { sInt t = GetWidth(ot,pi->CursorPos); sInt w = 2; if(pi->Overwrite) { if(pi->CursorPos<ol) w = GetWidth(ot+pi->CursorPos,1); else w = GetWidth(L" ",1); } sRectInvert2D(ox+t,rc->y0,ox+t+w,rc->y1); } break; case sPIM_POINT2POS: if(pi->QueryY>=rc->y0 && pi->QueryY<rc->y1) { x = ox; sInt i; for(i=0;i<len;i++) { x += GetWidth(ot+i,1); if(pi->QueryX < x) break; } pi->QueryPos = ot+i; pi->Mode = sPIM_QUERYDONE; } break; case sPIM_POS2POINT: if(pi->QueryPos>=ot && pi->QueryPos<=ot+len) { pi->QueryY = rc->y0; pi->QueryX = ox+GetWidth(ot,sInt(pi->QueryPos-ot)); } break; } }
void PageWin::AddOps(sU32 rcid) { sU32 cid; sInt i,j; sInt added,column; sMenuFrame *mf; // sInt key,chr; // sU8 keys[26]; sBool ok; mf = new sMenuFrame; mf->AddMenu("Misc" ,CMD_POPMISC ,'1')->BackColor = App->ClassColor(0); mf->AddMenu("Texture" ,CMD_POPTEX ,'2')->BackColor = App->ClassColor(sCID_GENBITMAP); mf->AddMenu("Mesh" ,CMD_POPMESH ,'3')->BackColor = App->ClassColor(sCID_GENMESH); mf->AddMenu("Scene" ,CMD_POPSCENE,'4')->BackColor = App->ClassColor(sCID_GENSCENE); mf->AddMenu("Material",CMD_POPMAT ,'5')->BackColor = App->ClassColor(sCID_GENMATERIAL); mf->AddMenu("FXChain" ,CMD_POPFX ,'6')->BackColor = App->ClassColor(sCID_GENFXCHAIN); // sSetMem(keys,0,26); for(column=0;column<6;column++) { added = 0; for(i=App->ClassCount-1;i>=0;i--) { j = sMin(App->ClassList[i].InputCount,2); if(j>=1) j++; if(App->ClassList[i].InputFlags&SCFU_ROWA) j=0; if(App->ClassList[i].InputFlags&SCFU_ROWB) j=3; if(App->ClassList[i].InputFlags&SCFU_ROWC) j=1; ok = sFALSE; cid = rcid; if(cid==0 && column==0) { j = column; cid = sCID_GENSPLINE; } if(cid==0 && column==1) { j = column; cid = sCID_GENPARTICLES; } if(j==column && (App->ClassList[i].InputFlags&0x0f)!=0) { if(cid!=0) if(App->ClassList[i].OutputCID==cid || (App->ClassList[i].OutputCID==0 && App->ClassList[i].InputCID[0]==cid)) ok = sTRUE; if(cid==sCID_GENMATERIAL) if(App->ClassList[i].InputCID[0]==sCID_GENMATPASS || App->ClassList[i].OutputCID==sCID_GENMATPASS) ok = sTRUE; } if(ok) { if(added==0) mf->AddColumn(); added++; /* chr = App->ClassList[i].Name[0]; key = -1; if(chr>='a' && chr<'z') key = chr-'a'; if(chr>='A' && chr<'Z') key = chr-'A'; chr = 0; if(key>=0 && keys[key]==0) { chr = key+'a'; keys[key]++; } else if(key>=0 && keys[key]==1) { chr = key+'A'+sKEYQ_SHIFT; keys[key]++; } */ mf->AddMenu(App->ClassList[i].Name,1024+i,App->ClassList[i].Shortcut); } } } mf->AddBorder(new sNiceBorder); mf->SendTo = this; if(OpWindowX==-1) { sGui->GetMouse(OpWindowX,OpWindowY); OpWindowX -= 24; if(OpWindowX<0) OpWindowX = 0; OpWindowY -= 5; if(OpWindowY<0) OpWindowY = 0; } sGui->AddWindow(mf,OpWindowX,OpWindowY); }
void sBSpline::FitToCurve(const sCurveSamplePoint *points,sInt nPoints,sF32 skipThresh,sF32 maxError) { if(nPoints < 2) return; // What this function does is generate a list of simple sample points // plus an initial knot vector for the actual approximation functions // to work with. sArray<Sample> samples; samples.Init(nPoints); Knots.Count = 0; // Find time range of samples sF32 minTime = points[0].Time, maxTime = points[0].Time; for(sInt i=1; i<nPoints; i++) { minTime = sMin(minTime,points[i].Time); maxTime = sMax(maxTime,points[i].Time); } // Generate sample points, plus knots at discontinuities for(sInt i=0; i<nPoints; i++) { sF32 time = (points[i].Time - minTime) / (maxTime - minTime); // Add value sample everywhere Sample *smp = samples.Add(); smp->Time = time; smp->Value = points[i].Value; smp->Type = 0; // Add derivative sample if the derivative exists sBool derivExists = (points[i].Flags & 3) == 3 && sFAbs(points[i].DerivLeft - points[i].DerivRight) < 1e-6f; if(derivExists && (points[i].Flags & 4)) { Sample *smp = samples.Add(); smp->Time = time; smp->Value = points[i].DerivLeft; smp->Type = 1; } // Discontinuity checking sInt discontinuityOrder = Degree + 1; if(!derivExists && (points[i].Flags & 3)) // C^1 discontinuity discontinuityOrder = 1; // C^0 discontinuity? if(i == 0 || i == nPoints - 1 || sFAbs(points[i].Value - points[i-1].Value) > skipThresh) discontinuityOrder = 0; // Add knots as necessary for(sInt j=discontinuityOrder; j<=Degree; j++) *Knots.Add() = time; } Values.Resize(Knots.Count); // Perform actual curve fitting FitCurveImpl(&samples[0],samples.Count,maxError,8); samples.Exit(); }