void ImgCodeBook::FromImage(Image32 *pImg, Color *pForceColor) { long Size; Color *pPix, *pDest; long x, y; long Width, Height; cbVector V; assert(CodeSize == 4); Width = pImg->GetXSize(); Height = pImg->GetYSize(); Size = Width * Height; SetSize(Size); pPix = pImg->GetPixels(); pDest = (Color *)V.GetPtr(); // Aim a color pointer at our vector for(y=0; y<Height; y++) { for(x=0; x<Width; x++) { *pDest = pPix[x]; // Copy the color into the vector AddVector(V); } pPix += Width; } if(pForceColor != 0) { *pDest = *pForceColor; // Copy the force color into the vector for(x=0; x<Size; x++) AddVector(V); // add the force color as many times as there are pixels in the image, to make it important } }
void AnimaMappedValues::AddVector(const AnimaString& propertyName, AnimaVertex4f value) { AnimaString pName = _uniqueName + propertyName + ".valueGenerator"; AnimaVectorGenerator* generator = _dataGeneratorManager->CreateVectorGenerator(pName); if (generator == nullptr) { int i = 1; AnimaString suffix = FormatString(".valueGenerator.%d", i); while (generator == nullptr) { generator = _dataGeneratorManager->CreateVectorGenerator(pName + suffix); i++; suffix = FormatString(".valueGenerator.%d", i); } } generator->SetGeneratedFromMappedValues(true); generator->SetVector(value); AddVector(propertyName, generator); }
void CLoadASE::ComputeNormals(t3DModel *pModel) { CVector3 vVector1, vVector2, vNormal, vPoly[3]; if(pModel->numOfObjects <= 0) return; for(int index = 0; index < pModel->numOfObjects; index++) { t3DObject *pObject = &(pModel->pObject[index]); CVector3 *pNormals = new CVector3 [pObject->numOfFaces]; CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces]; pObject->pNormals = new CVector3 [pObject->numOfVerts]; for(int i=0; i < pObject->numOfFaces; i++) { vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; vVector1 = Vector(vPoly[0], vPoly[2]); vVector2 = Vector(vPoly[2], vPoly[1]); vNormal = Cross(vVector1, vVector2); pTempNormals[i] = vNormal; vNormal = Normalize(vNormal); pObject->pFaces[i].Normal=MultiplieVectorByScaler(vNormal,-1.0f); pNormals[i] = vNormal; } CVector3 vSum = {0.0, 0.0, 0.0}; CVector3 vZero = vSum; int shared=0; for(int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) { if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempNormals[j]); shared++; } } pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared)); pObject->pNormals[i] = Normalize(pObject->pNormals[i]); vSum = vZero; shared = 0; } delete [] pTempNormals; delete [] pNormals; } }
void SubtractVector(float* vector1, float* vector2, float* result) { float temp[3]; CopyVector(vector2, temp); for(int i=0; i<3; i++) { temp[i] *= -1.0; } AddVector(vector1, temp, result); }
void hgemitter::GetCircleAngle( VECTOR *res, float rot ) { VECTOR padd; padd.x = angmul.x * rot; padd.y = angmul.y * rot; padd.z = angmul.z * rot; AddVector( res, &padd, &angopt ); }
void hgemitter::GetBasePosition( VECTOR *res, VECTOR *in ) { VECTOR padd; if ( size.x == 0.0f ) padd.x = 0.0f; else padd.x = ((float)(rand()&4095) * FRND_4096 ) * size.x; if ( size.y == 0.0f ) padd.y = 0.0f; else padd.y = ((float)(rand()&4095) * FRND_4096 ) * size.y; if ( size.z == 0.0f ) padd.z = 0.0f; else padd.z = ((float)(rand()&4095) * FRND_4096 ) * size.z; AddVector( res, in, &padd ); }
void AnimaMappedValues::SetVector(const AnimaString& propertyName, AnimaVectorGenerator* value) { AnimaString pName = _uniqueName + propertyName; if (_vectorsMap.find(pName) == _vectorsMap.end()) AddVector(propertyName, value); else _vectorsMap[pName] = value; }
void hgemitter::GetAngle( VECTOR *res ) { VECTOR padd; if ( angmul.x == 0.0f ) padd.x = 0.0f; else padd.x = ((float)(rand()&4095) * PI2_4096 ) * angmul.x; if ( angmul.y == 0.0f ) padd.y = 0.0f; else padd.y = ((float)(rand()&4095) * PI2_4096 ) * angmul.y; if ( angmul.z == 0.0f ) padd.z = 0.0f; else padd.z = ((float)(rand()&4095) * PI2_4096 ) * angmul.z; AddVector( res, &padd, &angopt ); }
// 下面的函数用于计算对象的法向量 void CLoad3DS::ComputeNormals(t3DModel *pModel) { CVector3 vVector1, vVector2, vNormal, vPoly[3]; // 如果模型中没有对象,则返回 if(pModel->numOfObjects <= 0) return; // 遍历模型中所有的对象 for(int index = 0; index < pModel->numOfObjects; index++) { // 获得当前的对象 t3DObject *pObject = &(pModel->pObject[index]); // 分配需要的存储空间 CVector3 *pNormals = new CVector3 [pObject->numOfFaces]; CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces]; pObject->pNormals = new CVector3 [pObject->numOfVerts]; // 遍历对象的所有面 for(int i=0; i < pObject->numOfFaces; i++) { vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; // 计算面的法向量 vVector1 = Vector(vPoly[0], vPoly[2]); // 获得多边形的矢量 vVector2 = Vector(vPoly[2], vPoly[1]); // 获得多边形的第二个矢量 vNormal = Cross(vVector1, vVector2); // 获得两个矢量的叉积 pTempNormals[i] = vNormal; // 保存非规范化法向量 vNormal = Normalize(vNormal); // 规范化获得的叉积 pNormals[i] = vNormal; // 将法向量添加到法向量列表中 } // 下面求顶点法向量 CVector3 vSum = {0.0, 0.0, 0.0}; CVector3 vZero = vSum; int shared=0; // 遍历所有的顶点 for (int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) // 遍历所有的三角形面 { // 判断该点是否与其它的面共享 if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempNormals[j]); shared++; } } pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared)); // 规范化最后的顶点法向 pObject->pNormals[i] = Normalize(pObject->pNormals[i]); vSum = vZero; shared = 0; } // 释放存储空间,开始下一个对象 delete [] pTempNormals; delete [] pNormals; } }
ssize_t SVectorIO::AddVector(const iovec* vector, size_t count) { ssize_t pos = m_vectorCount; while (count-- > 0) { pos = AddVector(vector->iov_base, vector->iov_len); if (pos < B_OK) break; vector++; } return pos; }
void AnimaMappedValues::SetVector(const AnimaString& propertyName, AnimaVertex4f value) { AnimaString pName = _uniqueName + propertyName + ".valueGenerator"; AnimaVectorGenerator* generator = (AnimaVectorGenerator*)_dataGeneratorManager->GetGenerator(pName); if (generator == nullptr) AddVector(propertyName, value); else { generator->SetVector(value); } }
void TraverseBvhTree(BvhNode* node, const Ray &ray, std::vector<Primitive*> &objects) { if (node->box.IsIntersect(ray)) { if (node->IsLeaf()) { AddVector(objects, node->objects); } else { TraverseBvhTree(node->leftNode, ray, objects); TraverseBvhTree(node->rightNode, ray, objects); } } }
void* SVectorIO::Allocate(size_t length) { ssize_t result = B_NO_MEMORY; alloc_data* ad = &m_localData; if ((ad->next_pos+length) > ad->size) { ad = NULL; if (!m_heapData) m_heapData = new SVector<alloc_data*>; if (m_heapData) { if (length < (MAX_LOCAL_DATA/2)) { const int32_t N = m_heapData->CountItems(); ad = m_heapData->ItemAt(N-1); if ((ad->next_pos+length) > ad->size) { ad = static_cast<alloc_data*>( malloc(sizeof(alloc_data) + MAX_LOCAL_DATA)); if (ad) result = m_heapData->AddItem(ad); if (result >= B_OK) { ad->size = MAX_LOCAL_DATA; ad->next_pos = 0; } else { free(ad); ad = NULL; } } } if (!ad) { ad = static_cast<alloc_data*>( malloc(sizeof(alloc_data) + length)); if (ad) result = m_heapData->AddItemAt(ad, 0); if (result >= B_OK) { ad->size = length; ad->next_pos = 0; } else { free(ad); ad = NULL; } } } } if (ad) { void* data = reinterpret_cast<uint8_t*>(ad+1)+ad->next_pos; result = AddVector(data, length); if (result >= B_OK) { ad->next_pos += length; return data; } } m_vectorCount = result; return NULL; }
// Note we are adding uint32_t's as *signed* int32's (using _mm_add_epi32). But // that's ok since the histogram values are less than 1<<28 (max picture size). static void HistogramAdd(const VP8LHistogram* const a, const VP8LHistogram* const b, VP8LHistogram* const out) { int i; const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_); assert(a->palette_code_bits_ == b->palette_code_bits_); if (b != out) { AddVector(a->literal_, b->literal_, out->literal_, NUM_LITERAL_CODES); AddVector(a->red_, b->red_, out->red_, NUM_LITERAL_CODES); AddVector(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES); AddVector(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES); } else { AddVectorEq(a->literal_, out->literal_, NUM_LITERAL_CODES); AddVectorEq(a->red_, out->red_, NUM_LITERAL_CODES); AddVectorEq(a->blue_, out->blue_, NUM_LITERAL_CODES); AddVectorEq(a->alpha_, out->alpha_, NUM_LITERAL_CODES); } for (i = NUM_LITERAL_CODES; i < literal_size; ++i) { out->literal_[i] = a->literal_[i] + b->literal_[i]; } for (i = 0; i < NUM_DISTANCE_CODES; ++i) { out->distance_[i] = a->distance_[i] + b->distance_[i]; } }
void ImgCodeBook::FromImageUnique(Image32 *pImg, Color* pForceColor) { long Size; Color *pPix, *pDest; long x, y; long Width, Height; cbVector V, f; assert(CodeSize == 4); Width = pImg->GetXSize(); Height = pImg->GetYSize(); Size = Width * Height; SetSize(Size); pPix = pImg->GetPixels(); for(y=0; y<Height; y++) { pDest = (Color *)V.GetPtr(); for(x=0; x<Width; x++) { *pDest = pPix[x]; AddVectorUnique(V); } pPix += Width; } if(pForceColor != 0) { *pDest = *pForceColor; // Copy the force color into the vector for(x=0; x<Size; x++) AddVector(V); // add the force color as many times as there are pixels in the image, to make it important } //char szText[512]; //wsprintf(szText, "Built %d unique codes\n", VectList.Count()); //OutputDebugString(szText); }
void UpdatePosition(XYPair* position, XYPair* velocity, double* angle, int const & maxX, int const & maxY) { *position = AddVector(*position, *velocity); *angle += ROTATION_PER_FRAME; if (*angle > 360.0) { *angle -= 360.0; } // Check x bounds if (position->x < 0) { printf("Reflected off of the left fence\n"); position->x *= -1; velocity->x *= -1; } if (position->x > maxX) { printf("Reflected off of the left fence\n"); position->x = maxX - (position->x - maxX); velocity->x *= -1; } if (position->y < 0) { printf("Reflected off the top fence\n"); position->y *= -1; velocity->y *= -1; } if (position->y > maxY) { printf("Reflected off of the bottom fence\n"); position->y = maxY - (position->y - maxY); velocity->y *= -1; } }
void TRWS::optimizeAlg(int nIterations) { assert(m_type != NONE); if (m_grid_graph) { switch (m_type) { case L1: optimize_GRID_L1(nIterations); break; case L2: optimize_GRID_L2(nIterations); break; case FIXED_MATRIX: optimize_GRID_FIXED_MATRIX(nIterations); break; case GENERAL: optimize_GRID_GENERAL(nIterations); break; case BINARY: optimize_GRID_BINARY(nIterations); break; default: assert(0); exit(1); } } else {printf("\nNot implemented for general graphs yet, exiting!");exit(1);} // printf("lower bound = %f\n", m_lowerBound); //////////////////////////////////////////////// // computing solution // //////////////////////////////////////////////// if (m_type != BINARY) { int x, y, n, K = m_nLabels; CostVal* D_ptr; REAL* M_ptr; REAL* Di; REAL delta; int ki, kj; Di = new REAL[K]; n = 0; D_ptr = m_D; M_ptr = m_messages; for (y=0; y<m_height; y++) for (x=0; x<m_width; x++, D_ptr+=K, M_ptr+=2*K, n++) { CopyVector(Di, D_ptr, K); if (m_type == GENERAL) { if (m_V) { CostVal* ptr = m_V + 2*(x+y*m_width-1)*K*K; if (x > 0) { kj = m_answer[n-1]; for (ki=0; ki<K; ki++) { Di[ki] += ptr[kj + ki*K]; } } ptr -= (2*m_width-3)*K*K; if (y > 0) { kj = m_answer[n-m_width]; for (ki=0; ki<K; ki++) { Di[ki] += ptr[kj + ki*K]; } } } else { if (x > 0) { kj = m_answer[n-1]; for (ki=0; ki<K; ki++) { Di[ki] += m_smoothFn(n, n-1, ki, kj); } } if (y > 0) { kj = m_answer[n-m_width]; for (ki=0; ki<K; ki++) { Di[ki] += m_smoothFn(n, n-m_width, ki, kj); } } } } else // m_type == L1, L2 or FIXED_MATRIX { if (x > 0) { kj = m_answer[n-1]; CostVal lambda = (m_varWeights) ? m_horzWeights[n-1] : 1; for (ki=0; ki<K; ki++) { Di[ki] += lambda*m_V[kj*K + ki]; } } if (y > 0) { kj = m_answer[n-m_width]; CostVal lambda = (m_varWeights) ? m_vertWeights[n-m_width] : 1; for (ki=0; ki<K; ki++) { Di[ki] += lambda*m_V[kj*K + ki]; } } } if (x < m_width-1) AddVector(Di, M_ptr, K); // message (x+1,y)->(x,y) if (y < m_height-1) AddVector(Di, M_ptr+K, K); // message (x,y+1)->(x,y) // compute min delta = Di[0]; m_answer[n] = 0; for (ki=1; ki<K; ki++) { if (delta > Di[ki]) { delta = Di[ki]; m_answer[n] = ki; } } } delete [] Di; } else // m_type == BINARY { int x, y, n; REAL* M_ptr; REAL Di; n = 0; M_ptr = m_messages; for (y=0; y<m_height; y++) for (x=0; x<m_width; x++, M_ptr+=2, n++) { Di = m_DBinary[n]; if (x > 0) Di += (m_answer[n-1] == 0) ? m_horzWeightsBinary[n-1] : -m_horzWeightsBinary[n-1]; if (y > 0) Di += (m_answer[n-m_width] == 0) ? m_vertWeightsBinary[n-m_width] : -m_vertWeightsBinary[n-m_width]; if (x < m_width-1) Di += M_ptr[0]; // message (x+1,y)->(x,y) if (y < m_height-1) Di += M_ptr[1]; // message (x,y+1)->(x,y) // compute min m_answer[n] = (Di >= 0) ? 0 : 1; } } }
void Terrain::ComputeNormals() { float *norm1,*norm2,*norm3,*norm4; int i,j,k; if (normals == NULL) return; for(i = 0; i < length; i++) for(j = 0; j < width; j++) { norm1 = NULL; norm2 = NULL; norm3 = NULL; norm4 = NULL; if (i == 0 && j == 0) { norm1 = CrossProduct(0,0, 0,1, 1,0); NormalizeVector(norm1); } else if (j == width-1 && i == length-1) { norm1 = CrossProduct(i,j, j,i-1, j-1,i); NormalizeVector(norm1); } else if (j == 0 && i == length-1) { norm1 = CrossProduct(i,j, j,i-1, j+1,i); NormalizeVector(norm1); } else if (j == width-1 && i == 0) { norm1 = CrossProduct(i,j, j,i+1, j-1,i); NormalizeVector(norm1); } else if (i == 0) { norm1 = CrossProduct(j,0, j-1,0, j,1); NormalizeVector(norm1); norm2 = CrossProduct(j,0,j,1,j+1,0); NormalizeVector(norm2); } else if (j == 0) { norm1 = CrossProduct(0,i, 1,i, 0,i-1); NormalizeVector(norm1); norm2 = CrossProduct(0,i, 0,i+1, 1,i); NormalizeVector(norm2); } else if (i == length) { norm1 = CrossProduct(j,i, j,i-1, j+1,i); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j+1,i, j,i-1); NormalizeVector(norm2); } else if (j == width) { norm1 = CrossProduct(j,i, j,i-1, j-1,i); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j-1,i, j,i+1); NormalizeVector(norm2); } else { norm1 = CrossProduct(j,i, j-1,i, j,i+1); NormalizeVector(norm1); norm2 = CrossProduct(j,i, j,i+1, j+1,i); NormalizeVector(norm2); norm3 = CrossProduct(j,i, j+1,i, j,i-1); NormalizeVector(norm3); norm4 = CrossProduct(j,i, j,i-1, j-1,i); NormalizeVector(norm4); } if (norm2 != NULL) { AddVector(norm1,norm2); free(norm2); } if (norm3 != NULL) { AddVector(norm1,norm3); free(norm3); } if (norm4 != NULL) { AddVector(norm1,norm4); free(norm4); } NormalizeVector(norm1); norm1[2] = - norm1[2]; for (k = 0; k< 3; k++) normals[3*(i*width + j) + k] = norm1[k]; free(norm1); } }
void AnimaMappedValues::AddVector(const AnimaString& propertyName, AFloat x, AFloat y, AFloat z, AFloat w) { AnimaVertex4f vector(x, y, z, w); AddVector(propertyName, vector); }
// Archive the results if it is time void ArchiveData::ArchiveVTKFile(double atime,vector< int > quantity,vector< int > quantitySize, vector< char * > quantityName,double **vtk) { char fname[300],fline[300]; // get relative path name to the file sprintf(fname,"%s%s_%d.vtk",outputDir,archiveRoot,fmobj->mstep); // open the file ofstream afile; afile.open(fname, ios::out); if(!afile.is_open()) FileError("Cannot open a vtk archive file",fname,"ArchiveData::ArchiveVTKFile"); // required header line afile << "# vtk DataFile Version 4.2" << endl; // title sprintf(fline,"step:%d time:%15.7e ms",fmobj->mstep,1000.*atime); afile << fline << endl; // header afile << "ASCII" << endl; afile << "DATASET STRUCTURED_POINTS" << endl; int ptx,pty,ptz; mpmgrid.GetGridPoints(&ptx,&pty,&ptz); afile << "DIMENSIONS " << ptx << " " << pty; if(fmobj->IsThreeD()) afile << " " << ptz << endl; else afile << " 1" << endl; afile << "ORIGIN " << mpmgrid.xmin << " " << mpmgrid.ymin; if(fmobj->IsThreeD()) afile << " " << mpmgrid.zmin << endl; else afile << " 0" << endl; afile << "SPACING " << mpmgrid.gridx << " " << mpmgrid.gridy; if(fmobj->IsThreeD()) afile << " " << mpmgrid.gridz << endl; else afile << " " << mpmgrid.gridx << endl; afile << "POINT_DATA " << nnodes << endl; // export selected data int i,offset=0; unsigned int q; double *vtkquant=NULL; double scale=1.; // contact force special case int archiveStepInterval=1; if(GetDoingArchiveContact()) { archiveStepInterval=fmobj->mstep-lastArchiveContactStep; lastArchiveContactStep=fmobj->mstep; ZeroVector(&lastContactForce); } for(q=0;q<quantity.size();q++) { // header for next quantity switch(quantitySize[q]) { case 1: if(vtk==NULL) break; case -1: afile << "SCALARS "; afile << quantityName[q]; afile << " double 1" << endl; afile << "LOOKUP_TABLE default" << endl; break; case 3: if(vtk==NULL) break; case -3: afile << "VECTORS "; afile << quantityName[q]; afile << " double" << endl; break; case 6: if(vtk==NULL) break; afile << "TENSORS "; afile << quantityName[q]; afile << " double" << endl; break; default: break; } // the quantity for each node for(i=1;i<=nnodes;i++) { if(vtk!=NULL) vtkquant=vtk[i]; switch(quantity[q]) { case VTK_MASS: // mass in g afile << nd[i]->mass << endl; break; case VTK_TEMPERATURE: afile << nd[i]->gTemperature << endl; break; case VTK_RIGIDCONTACTFORCES: { Vector fcontact=nd[i]->GetTotalContactForce(TRUE); ScaleVector(&fcontact,-1./(double)archiveStepInterval); // force of rigid particles on the object // average over steps since last archive afile << fcontact.x << " " << fcontact.y << " " << fcontact.z << endl; AddVector(&lastContactForce,&fcontact); break; } case VTK_BCFORCES: if(nd[i]->fixedDirection&XYZ_SKEWED_DIRECTION) { //Vector fbc = nd[i]->GetCMatFtot(); //afile << fbc.x << " " << fbc.y << " " << fbc.z << endl; } else afile << "0. 0. 0." << endl; break; case VTK_CONCENTRATION: case VTK_WORKENERGY: case VTK_PLASTICENERGY: case VTK_MATERIAL: case VTK_HEATENERGY: case VTK_PRESSURE: case VTK_EQUIVSTRESS: case VTK_RELDELTAV: case VTK_EQUIVSTRAIN: if(vtk==NULL) break; afile << vtkquant[offset] << endl; break; case VTK_VELOCITY: // extraplated to always get cm velocity case VTK_DISPLACEMENT: // Displacement in mm if(vtk==NULL) break; afile << vtkquant[offset] << " " << vtkquant[offset+1] << " " << vtkquant[offset+2] << endl; break; case VTK_PLASTICSTRAIN: scale=1.; case VTK_STRESS: if(quantity[q]==VTK_STRESS) scale=1.e-6; case VTK_STRAIN: case VTK_TOTALSTRAIN: if(quantity[q]==VTK_STRAIN || quantity[q]==VTK_TOTALSTRAIN) scale=1.; // stress in MPa, Strains absolute if(vtk==NULL) break; afile << scale*vtkquant[offset] << " " << scale*vtkquant[offset+3] << " " << scale*vtkquant[offset+4] << endl; afile << scale*vtkquant[offset+3] << " " << scale*vtkquant[offset+1] << " " << scale*vtkquant[offset+5] << endl; afile << scale*vtkquant[offset+4] << " " << scale*vtkquant[offset+5] << " " << scale*vtkquant[offset+2] << endl; break; default: break; } } // offset for next quantity (if in the buffer) if(quantitySize[q]>0) offset+=quantitySize[q]; } // close the file afile.close(); if(afile.bad()) FileError("File error closing a vtk archive file",fname,"ArchiveData::ArchiveVTKFile"); }
void* InitPlacedLight(void* bhdata,STRATEGYBLOCK *sbPtr) { TOOLS_DATA_PLACEDLIGHT *toolsData = (TOOLS_DATA_PLACEDLIGHT *)bhdata; PLACED_LIGHT_BEHAV_BLOCK* pl_bhv; int i; LOCALASSERT(sbPtr->I_SBtype == I_BehaviourPlacedLight); LOCALASSERT(toolsData); /* create, initialise and attach a data block */ pl_bhv = (void *)AllocateMem(sizeof(PLACED_LIGHT_BEHAV_BLOCK)); if(!pl_bhv) { memoryInitialisationFailure = 1; return ((void *)NULL); } pl_bhv->bhvr_type=I_BehaviourPlacedLight; sbPtr->SBdataptr = pl_bhv; /* these should be loaded */ /* set default indestructibility */ pl_bhv->Indestructable = No; /* Initialise object's stats */ { NPC_DATA *NpcData; NpcData=GetThisNpcData(I_NPC_DefaultInanimate); LOCALASSERT(NpcData); sbPtr->SBDamageBlock.Health=NpcData->StartingStats.Health<<ONE_FIXED_SHIFT; sbPtr->SBDamageBlock.Armour=NpcData->StartingStats.Armour<<ONE_FIXED_SHIFT; sbPtr->SBDamageBlock.SB_H_flags=NpcData->StartingStats.SB_H_flags; } pl_bhv->destruct_target_request=toolsData->destruct_target_request; for(i=0;i<SB_NAME_LENGTH;i++) { pl_bhv->destruct_target_ID[i]=toolsData->destruct_target_ID[i]; } pl_bhv->destruct_target_sbptr=0; pl_bhv->sequence=toolsData->sequence; pl_bhv->colour_red=toolsData->colour_red; pl_bhv->colour_green=toolsData->colour_green; pl_bhv->colour_blue=toolsData->colour_blue; pl_bhv->colour_diff_red=toolsData->colour_diff_red; pl_bhv->colour_diff_green=toolsData->colour_diff_green; pl_bhv->colour_diff_blue=toolsData->colour_diff_blue; pl_bhv->fade_up_time=toolsData->fade_up_time; pl_bhv->fade_down_time=toolsData->fade_down_time; pl_bhv->up_time=toolsData->up_time; pl_bhv->down_time=toolsData->down_time; pl_bhv->timer=toolsData->timer; pl_bhv->flicker_timer=0; pl_bhv->type=toolsData->type; pl_bhv->on_off_type=toolsData->on_off_type; pl_bhv->state=toolsData->state; pl_bhv->on_off_state=toolsData->on_off_state; pl_bhv->swap_colour_and_brightness_alterations=toolsData->swap_colour_and_brightness_alterations; pl_bhv->on_off_timer=0; sbPtr->SBDamageBlock.Health*=toolsData->integrity; if(toolsData->static_light) { sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC); } else { sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_INANIMATE); } if(!sbPtr->DynPtr) { RemoveBehaviourStrategy(sbPtr); return 0; } sbPtr->DynPtr->Mass = toolsData->mass; if (toolsData->integrity > 20) { pl_bhv->Indestructable = Yes; sbPtr->integrity = DEFAULT_OBJECT_INTEGRITY; } else if (toolsData->integrity < 1) { sbPtr->integrity = 1; // die immediately } else { sbPtr->integrity = (DEFAULT_OBJECT_INTEGRITY)*(toolsData->integrity); } pl_bhv->has_broken_sequence=1; pl_bhv->has_corona=0; /*check to see if object is animated.*/ /*also check for corona flag at the same time*/ { TXACTRLBLK **pptxactrlblk; int item_num; int shape_num = toolsData->shapeIndex; SHAPEHEADER *shptr = GetShapeData(shape_num); pptxactrlblk = &pl_bhv->inan_tac; for(item_num = 0; item_num < shptr->numitems; item_num ++) { POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]); LOCALASSERT(poly); SetupPolygonFlagAccessForShape(shptr); if((Request_PolyFlags((void *)poly)) & iflag_txanim) { TXACTRLBLK *pnew_txactrlblk; pnew_txactrlblk = AllocateMem(sizeof(TXACTRLBLK)); if(pnew_txactrlblk) { pnew_txactrlblk->tac_flags = 0; pnew_txactrlblk->tac_item = item_num; pnew_txactrlblk->tac_sequence = 0; pnew_txactrlblk->tac_node = 0; pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num); pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num); *pptxactrlblk = pnew_txactrlblk; pptxactrlblk = &pnew_txactrlblk->tac_next; { //see how many sequences there are int num_seq=0; while(pnew_txactrlblk->tac_txarray[num_seq+1])num_seq++; if(num_seq<3) pl_bhv->has_broken_sequence=0; GLOBALASSERT(num_seq>=2); } } else *pptxactrlblk = NULL; } if((Request_PolyFlags((void *)poly)) & iflag_light_corona) { int* vertexptr= &poly->Poly1stPt; int num_verts=0; pl_bhv->has_corona=1; pl_bhv->corona_location.vx=0; pl_bhv->corona_location.vy=0; pl_bhv->corona_location.vz=0; //take the average of all the points in the polygon while(*vertexptr!=-1) { num_verts++; AddVector((VECTORCH*)&shptr->points[0][(*vertexptr)*3],&pl_bhv->corona_location); vertexptr++; } pl_bhv->corona_location.vx/=num_verts; pl_bhv->corona_location.vy/=num_verts; pl_bhv->corona_location.vz/=num_verts; } } *pptxactrlblk=0; pl_bhv->light=toolsData->light; GLOBALASSERT(pl_bhv->light); pl_bhv->light->RedScale=pl_bhv->colour_red; pl_bhv->light->GreenScale=pl_bhv->colour_green; pl_bhv->light->BlueScale=pl_bhv->colour_blue; } if(!pl_bhv->inan_tac) { pl_bhv->has_broken_sequence=0; } SetTextureAnimationSequence(sbPtr->shapeIndex,pl_bhv->inan_tac,pl_bhv->sequence); /* Initialise the dynamics block */ { DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; GLOBALASSERT(dynPtr); dynPtr->PrevPosition = dynPtr->Position = toolsData->position; dynPtr->OrientEuler = toolsData->orientation; CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat); TransposeMatrixCH(&dynPtr->OrientMat); } /* strategy block initialisation */ sbPtr->shapeIndex = toolsData->shapeIndex; for(i=0;i<SB_NAME_LENGTH;i++) sbPtr->SBname[i] = toolsData->nameID[i]; UpdatePlacedLightState(pl_bhv,sbPtr); /* these must be initialised for respawning objects in multiplayer game */ pl_bhv->startingHealth = sbPtr->SBDamageBlock.Health; pl_bhv->startingArmour = sbPtr->SBDamageBlock.Armour; return((void*)pl_bhv); }
void TranslateVector(float x, float y, float z, float* result) { float temp[3] = {x,y,z}; AddVector(result,temp,result); }
void CLoadASE::ComputeTangents(t3DModel *pModel) { CVector3 vVector1, vVector2, vTangent, vBinormal, vPoly[3]; float vVector1s, vVector1t, vVector2s, vVector2t; float v1s, v1t, v2s, v2t, v3s, v3t; CVector3 vSum = {0.0, 0.0, 0.0}; CVector3 vZero = vSum; int shared=0; if(pModel->numOfObjects <= 0) return; for(int index = 0; index < pModel->numOfObjects; index++) { t3DObject *pObject = &(pModel->pObject[index]); CVector3 *pTangents = new CVector3 [pObject->numOfFaces]; CVector3 *pTempTangents = new CVector3 [pObject->numOfFaces]; pObject->pTangents = new CVector3 [pObject->numOfVerts]; CVector3 *pBinormals = new CVector3 [pObject->numOfFaces]; CVector3 *pTempBinormals = new CVector3 [pObject->numOfFaces]; pObject->pBinormals = new CVector3 [pObject->numOfVerts]; for(int i=0; i < pObject->numOfFaces; i++) { vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; v1s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[0]].x; v1t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[0]].y; v2s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[1]].x; v2t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[1]].y; v3s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[2]].x; v3t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[2]].y; vVector1 = Vector(vPoly[1], vPoly[0]); vVector2 = Vector(vPoly[2], vPoly[0]); vVector1s = v2s-v1s; vVector1t = v2t-v1t; vVector2s = v3s-v1s; vVector2t = v3t-v1t; float denominator = vVector1s * vVector2t - vVector2s * vVector1t; if(denominator < 0.0001f && denominator > -0.0001f) { vTangent.x = 1.0f; vTangent.y = 0.0f; vTangent.z = 0.0f; vBinormal.x = 0.0f; vBinormal.y = 1.0f; vBinormal.z = 0.0f; pTempTangents[i] = vTangent; pTempBinormals[i] = vBinormal; } else { float scale = 1.0f / denominator; CVector3 T, B, N; T.x = (vVector2t * vVector1.x - vVector1t * vVector2.x) * scale; T.y = (vVector2t * vVector1.y - vVector1t * vVector2.y) * scale; T.z = (vVector2t * vVector1.z - vVector1t * vVector2.z) * scale; B.x = (-vVector2s * vVector1.x + vVector1s * vVector2.x) * scale; B.y = (-vVector2s * vVector1.y + vVector1s * vVector2.y) * scale; B.z = (-vVector2s * vVector1.z + vVector1s * vVector2.z) * scale; N = pObject->pFaces[i].Normal; float scale2 = 1.0f / ((T.x * B.y * N.z - T.z * B.y * N.x) + (B.x * N.y * T.z - B.z * N.y * T.x) + (N.x * T.y * B.z - N.z * T.y * B.x)); vTangent.x = Cross(B, N).x * scale2; vTangent.y = -Cross(N, T).x * scale2; vTangent.z = Cross(T, B).x * scale2; pTempTangents[i] = vTangent; vTangent=Normalize(vTangent); vBinormal.x = -Cross(B, N).y * scale2; vBinormal.y = Cross(N, T).y * scale2; vBinormal.z = -Cross(T, B).y * scale2; pTempBinormals[i] = vBinormal; vBinormal=Normalize(vBinormal); } } vZero = vSum; shared=0; for(int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) { if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempTangents[j]); shared++; } } pObject->pTangents[i] = DivideVectorByScaler(vSum, float(shared)); pObject->pTangents[i] = Normalize(pObject->pTangents[i]); vSum = vZero; shared = 0; } delete [] pTempTangents; delete [] pTangents; vZero = vSum; shared=0; for(int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) { if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempBinormals[j]); shared++; } } pObject->pBinormals[i] = DivideVectorByScaler(vSum, float(-shared)); pObject->pBinormals[i] = Normalize(pObject->pBinormals[i]); vSum = vZero; shared = 0; } delete [] pTempBinormals; delete [] pBinormals; } }
/** computes the normals and vertex normals of the objects */ void Obj::computeNormals(tOBJModel *pmodel) { Vec3 vVector1, vVector2, vNormal, vPoly[3]; if (pmodel->numOfObjects <= 0) return; // if there are no objects, we can skip for (int index = 0; index < pmodel->numOfObjects; index++) { // for each of the objects tOBJObject *pobject = &(pmodel->pObject[index]); // get the current object Vec3 *pNormals = new Vec3 [pobject->numOfFaces]; Vec3 *pTempNormals = new Vec3 [pobject->numOfFaces]; pobject->pNormals = new Vec3 [pobject->numOfVerts]; for (int i=0; i < pobject->numOfFaces; i++) { // go though all of the faces // we extract the 3 points of this face int vx = pobject->pFaces[i].vertIndex[0]; int vy = pobject->pFaces[i].vertIndex[1]; int vz = pobject->pFaces[i].vertIndex[2]; int vc = pobject->numOfVerts; if (vx > vc || vy > vc || vz > vc) { error("Obj: vx=%d vy=%d vz=%d vc=%d", vx, vy, vz, vc); continue; //dax BUG: segfault } vPoly[0] = pobject->pVerts[pobject->pFaces[i].vertIndex[0]]; vPoly[1] = pobject->pVerts[pobject->pFaces[i].vertIndex[1]]; vPoly[2] = pobject->pVerts[pobject->pFaces[i].vertIndex[2]]; // let's calculate the face normals (get 2 vectors and find the cross product of those 2) vVector1 = Vector(vPoly[0], vPoly[2]); // get the vector of the polygon (we just need 2 sides) vVector2 = Vector(vPoly[2], vPoly[1]); // get a second vector of the polygon vNormal = Cross(vVector1, vVector2); // return the cross product of the 2 vectors pTempNormals[i] = vNormal; // save the un-normalized normal for the vertex normals vNormal = Normalize(vNormal); // normalize the cross product to give us the polygons normal pNormals[i] = vNormal; // assign the normal to the list of normals } Vec3 vSum = {0.0, 0.0, 0.0}; Vec3 vZero = vSum; int shared=0; // get the vertex normals for (int i=0; i < pobject->numOfVerts; i++) { // go through all of the vertices for (int j=0; j < pobject->numOfFaces; j++) {// go through all of the triangles // check if the vertex is shared by another face if (pobject->pFaces[j].vertIndex[0] == i || pobject->pFaces[j].vertIndex[1] == i || pobject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempNormals[j]); // add the unnormalized normal of the shared face shared++; // increase the number of shared triangles } } // get the normal by dividing the sum by the shared. we negate so normals pointing out. pobject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared)); // normalize the normal for the final vertex normal pobject->pNormals[i] = Normalize(pobject->pNormals[i]); vSum = vZero; // reset the sum shared = 0; // reset the shared } if (pTempNormals) delete[] pTempNormals; if (pNormals) delete[] pNormals; } }
/* Compute form-factors from the shooting patch to every elements */ static void ComputeFormfactors(unsigned long shootPatch) { unsigned long i; TVector3f up[5]; TPoint3f lookat[5]; TPoint3f center; TVector3f normal, tangentU, tangentV, vec; int face; double norm; TPatch* sp; double* fp; TElement* ep; /* get the center of shootPatch */ sp = &(params->patches[shootPatch]); center = sp->center; normal = sp->normal; /* rotate the hemi-cube along the normal axis of the patch randomly */ /* this will reduce the hemi-cube aliasing artifacts */ do { vec.x = RandomFloat; vec.y = RandomFloat; vec.z = RandomFloat; /* get a tangent vector */ CrossVector(tangentU, normal, vec); NormalizeVector(norm, tangentU); } while (norm==0); /* bad choice of the random vector */ /* compute tangentV */ CrossVector(tangentV, normal, tangentU); /* assign the lookats and ups for each hemicube face */ AddVector(lookat[0], center, normal); up[0] = tangentU; AddVector(lookat[1], center, tangentU); up[1] = normal; AddVector(lookat[2], center, tangentV); up[2] = normal; SubVector(lookat[3], center, tangentU); up[3] = normal; SubVector(lookat[4], center, tangentV); up[4] = normal; /* position the hemicube slightly above the center of the shooting patch */ ScaleVector(normal, params->worldSize*0.0001); AddVector(hemicube.view.camera, center, normal); /* clear the formfactors */ fp = formfactors; for (i=params->nElements; i--; fp++) *fp = 0.0; for (face=0; face < 5; face++) { hemicube.view.lookat = lookat[face]; hemicube.view.up = up[face]; /* draw elements */ BeginDraw(&(hemicube.view), kBackgroundItem); for (i=0; i< params->nElements; i++) DrawElement(¶ms->elements[i], i); /* color element i with its index */ EndDraw(); /* get formfactors */ if (face==0) SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.topFactors); else SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes/2, hemicube.view.buffer, hemicube.sideFactors); } /* compute reciprocal form-factors */ ep = params->elements; fp = formfactors; for (i=params->nElements; i--; ep++, fp++) { *fp *= sp->area / ep->area; /* This is a potential source of hemi-cube aliasing */ /* To do this right, we need to subdivide the shooting patch and reshoot. For now we just clip it to unity */ if ((*fp) > 1.0) *fp = 1.0; } }
void TRWS::optimize_GRID_FIXED_MATRIX(int nIterations) { int x, y, n, K = m_nLabels; CostVal* D_ptr; REAL* M_ptr; REAL* Di; void* buf; Di = new REAL[K]; buf = new REAL[K]; for ( ; nIterations > 0; nIterations --) { // forward pass n = 0; D_ptr = m_D; M_ptr = m_messages; for (y=0; y<m_height; y++) for (x=0; x<m_width; x++, D_ptr+=K, M_ptr+=2*K, n++) { CopyVector(Di, D_ptr, K); if (x > 0) AddVector(Di, M_ptr-2*K, K); // message (x-1,y)->(x,y) if (y > 0) AddVector(Di, M_ptr-(2*m_width-1)*K, K); // message (x,y-1)->(x,y) if (x < m_width-1) AddVector(Di, M_ptr, K); // message (x+1,y)->(x,y) if (y < m_height-1) AddVector(Di, M_ptr+K, K); // message (x,y+1)->(x,y) if (x < m_width-1) { CostVal lambda = (m_varWeights) ? m_horzWeights[n] : 1; UpdateMessageFIXED_MATRIX(M_ptr, Di, K, 0.5, lambda, m_V, buf); } if (y < m_height-1) { CostVal lambda = (m_varWeights) ? m_vertWeights[n] : 1; UpdateMessageFIXED_MATRIX(M_ptr+K, Di, K, 0.5, lambda, m_V, buf); } } // backward pass m_lowerBound = 0; n --; D_ptr -= K; M_ptr -= 2*K; for (y=m_height-1; y>=0; y--) for (x=m_width-1; x>=0; x--, D_ptr-=K, M_ptr-=2*K, n--) { CopyVector(Di, D_ptr, K); if (x > 0) AddVector(Di, M_ptr-2*K, K); // message (x-1,y)->(x,y) if (y > 0) AddVector(Di, M_ptr-(2*m_width-1)*K, K); // message (x,y-1)->(x,y) if (x < m_width-1) AddVector(Di, M_ptr, K); // message (x+1,y)->(x,y) if (y < m_height-1) AddVector(Di, M_ptr+K, K); // message (x,y+1)->(x,y) m_lowerBound += SubtractMin(Di, K); if (x > 0) { CostVal lambda = (m_varWeights) ? m_horzWeights[n-1] : 1; m_lowerBound += UpdateMessageFIXED_MATRIX(M_ptr-2*K, Di, K, 0.5, lambda, m_V, buf); } if (y > 0) { CostVal lambda = (m_varWeights) ? m_vertWeights[n-m_width] : 1; m_lowerBound += UpdateMessageFIXED_MATRIX(M_ptr-(2*m_width-1)*K, Di, K, 0.5, lambda, m_V, buf); } } } delete [] Di; delete [] (REAL *)buf; }
/* Compute form-factors from the shooting patch to every elements */ static void ComputeFormfactors(unsigned long shootPatch) { unsigned long i; TVector3f up[5]; TPoint3f lookat[5]; TPoint3f center; TVector3f normal, tangentU, tangentV, vec; int face; double norm; TPatch* sp; double* fp; TElement* ep; double plane_eq[4]; /* get the center of shootPatch */ sp = &(params->patches[shootPatch]); center = sp->center; normal = sp->normal; plane_eq[0] = (double)normal.x; plane_eq[1] = (double)normal.y; plane_eq[2] = (double)normal.z; plane_eq[3] = (double)-(normal.x*center.x + normal.y*center.y + normal.z*center.z); /* rotate the hemi-cube along the normal axis of the patch randomly */ /* this will reduce the hemi-cube aliasing artifacts */ do { vec.x = RandomFloat; vec.y = RandomFloat; vec.z = RandomFloat; /* get a tangent vector */ CrossVector(tangentU, normal, vec); NormalizeVector(norm, tangentU); } while (norm==0); /* bad choice of the random vector */ /* compute tangentV */ CrossVector(tangentV, normal, tangentU); /* assign the lookats and ups for each hemicube face */ AddVector(lookat[0], center, normal); up[0] = tangentU; AddVector(lookat[1], center, tangentU); up[1] = normal; AddVector(lookat[2], center, tangentV); up[2] = normal; SubVector(lookat[3], center, tangentU); up[3] = normal; SubVector(lookat[4], center, tangentV); up[4] = normal; /* position the hemicube slightly above the center of the shooting patch */ ScaleVector(normal, params->worldSize*0.00000001); AddVector(hemicube.view.camera, center, normal); /* clear the formfactors */ fp = formfactors; for (i=params->nElements; i--; fp++) *fp = 0.0; for (face=0; face < 5; face++) { hemicube.view.lookat = lookat[face]; hemicube.view.up = up[face]; /* draw elements */ if (bits_for_RGB == 24) { /* a 24-bit display */ BeginHCDraw(&(hemicube.view), kBackgroundItem, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); } else if (bits_for_RGB == 8) { /* an 8-bit display */ /* this is a quick hack to make it work for 8-bit displays maybe a better way could be found ??? */ part_of_id = 1; /* processing first half of polygon ids */ BeginHCDraw(&(hemicube.view), 255, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); part_of_id = 2; /* second half of polygon ids */ BeginHCDraw(&(hemicube.view), 255, plane_eq); for (i=0; i< params->nElements; i++) DrawHCElement(¶ms->elements[i], i); /* color element i with its index */ EndHCDraw(&(hemicube.view)); } else { printf("Unexpected bits per RGB colour, exiting"); //exit(0); } /* get formfactors */ if (face==0) SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.topFactors,0); else SumFactors(formfactors, hemicube.view.xRes, hemicube.view.yRes, hemicube.view.buffer, hemicube.sideFactors, hemicube.view.yRes/2); } /* compute reciprocal form-factors */ ep = params->elements; fp = formfactors; for (i=params->nElements; i--; ep++, fp++) { *fp *= sp->area / ep->area; /* This is a potential source of hemi-cube aliasing */ /* To do this right, we need to subdivide the shooting patch and reshoot. For now we just clip it to unity */ if ((*fp) > 1.0) *fp = 1.0; } }
void AnimaMappedValues::AddVector(const AnimaString& propertyName, AnimaVertex3f value) { AnimaVertex4f vector(value, 1.0f); AddVector(propertyName, vector); }
void CLoad3DS::ComputeNormals(t3DModel *pModel) { CVector3 vVector1, vVector2, vNormal, vPoly[3]; // If there are no objects, we can skip this part if(pModel->numOfObjects <= 0) return; // What are vertex normals? And how are they different from other normals? // Well, if you find the normal to a triangle, you are finding a "Face Normal". // If you give OpenGL a face normal for lighting, it will make your object look // really flat and not very round. If we find the normal for each vertex, it makes // the smooth lighting look. This also covers up blocky looking objects and they appear // to have more polygons than they do. Basically, what you do is first // calculate the face normals, then you take the average of all the normals around each // vertex. It's just averaging. That way you get a better approximation for that vertex. // Go through each of the objects to calculate their normals for(int index = 0; index < pModel->numOfObjects; index++) { // Get the current object t3DObject *pObject = &(pModel->pObject[index]); // Here we allocate all the memory we need to calculate the normals CVector3 *pNormals = new CVector3 [pObject->numOfFaces]; CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces]; pObject->pNormals = new CVector3 [pObject->numOfVerts]; // Go though all of the faces of this object for(int i=0; i < pObject->numOfFaces; i++) { // To cut down LARGE code, we extract the 3 points of this face vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; // Now let's calculate the face normals (Get 2 vectors and find the cross product of those 2) vVector1 = Vector(vPoly[0], vPoly[2]); // Get the vector of the polygon (we just need 2 sides for the normal) vVector2 = Vector(vPoly[2], vPoly[1]); // Get a second vector of the polygon vNormal = Cross(vVector1, vVector2); // Return the cross product of the 2 vectors (normalize vector, but not a unit vector) pTempNormals[i] = vNormal; // Save the un-normalized normal for the vertex normals vNormal = Normalize(vNormal); // Normalize the cross product to give us the polygons normal pNormals[i] = vNormal; // Assign the normal to the list of normals } //////////////// Now Get The Vertex Normals ///////////////// CVector3 vSum = {0.0, 0.0, 0.0}; CVector3 vZero = vSum; int shared=0; for (int i = 0; i < pObject->numOfVerts; i++) // Go through all of the vertices { for (int j = 0; j < pObject->numOfFaces; j++) // Go through all of the triangles { // Check if the vertex is shared by another face if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempNormals[j]);// Add the un-normalized normal of the shared face shared++; // Increase the number of shared triangles } } // Get the normal by dividing the sum by the shared. We negate the shared so it has the normals pointing out. pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared)); // Normalize the normal for the final vertex normal pObject->pNormals[i] = Normalize(pObject->pNormals[i]); vSum = vZero; // Reset the sum shared = 0; // Reset the shared } // Free our memory and start over on the next object delete [] pTempNormals; delete [] pNormals; } }
void TRWS::optimize_GRID_GENERAL(int nIterations) { int x, y, n, K = m_nLabels; CostVal* D_ptr; REAL* M_ptr; REAL* Di; void* buf; Di = new REAL[K]; buf = new REAL[K]; for ( ; nIterations > 0; nIterations --) { // forward pass n = 0; D_ptr = m_D; M_ptr = m_messages; CostVal* V_ptr = m_V; for (y=0; y<m_height; y++) for (x=0; x<m_width; x++, D_ptr+=K, M_ptr+=2*K, V_ptr+=2*K*K, n++) { CopyVector(Di, D_ptr, K); if (x > 0) AddVector(Di, M_ptr-2*K, K); // message (x-1,y)->(x,y) if (y > 0) AddVector(Di, M_ptr-(2*m_width-1)*K, K); // message (x,y-1)->(x,y) if (x < m_width-1) AddVector(Di, M_ptr, K); // message (x+1,y)->(x,y) if (y < m_height-1) AddVector(Di, M_ptr+K, K); // message (x,y+1)->(x,y) if (x < m_width-1) { if (m_V) UpdateMessageGENERAL(M_ptr, Di, K, 0.5, /* forward dir*/ 0, V_ptr, buf); else UpdateMessageGENERAL(M_ptr, Di, K, 0.5, m_smoothFn, n, n+1, buf); } if (y < m_height-1) { if (m_V) UpdateMessageGENERAL(M_ptr+K, Di, K, 0.5, /* forward dir*/ 0, V_ptr+K*K, buf); else UpdateMessageGENERAL(M_ptr+K, Di, K, 0.5, m_smoothFn, n, n+m_width, buf); } } // backward pass m_lowerBound = 0; n --; D_ptr -= K; M_ptr -= 2*K; V_ptr -= 2*K*K; for (y=m_height-1; y>=0; y--) for (x=m_width-1; x>=0; x--, D_ptr-=K, M_ptr-=2*K, V_ptr-=2*K*K, n--) { CopyVector(Di, D_ptr, K); if (x > 0) AddVector(Di, M_ptr-2*K, K); // message (x-1,y)->(x,y) if (y > 0) AddVector(Di, M_ptr-(2*m_width-1)*K, K); // message (x,y-1)->(x,y) if (x < m_width-1) AddVector(Di, M_ptr, K); // message (x+1,y)->(x,y) if (y < m_height-1) AddVector(Di, M_ptr+K, K); // message (x,y+1)->(x,y) // normalize Di, update lower bound m_lowerBound += SubtractMin(Di, K); if (x > 0) { if (m_V) m_lowerBound += UpdateMessageGENERAL(M_ptr-2*K, Di, K, 0.5, /* backward dir */ 1, V_ptr-2*K*K, buf); else m_lowerBound += UpdateMessageGENERAL(M_ptr-2*K, Di, K, 0.5, m_smoothFn, n, n-1, buf); } if (y > 0) { if (m_V) m_lowerBound += UpdateMessageGENERAL(M_ptr-(2*m_width-1)*K, Di, K, 0.5, /* backward dir */ 1, V_ptr-(2*m_width-1)*K*K, buf); else m_lowerBound += UpdateMessageGENERAL(M_ptr-(2*m_width-1)*K, Di, K, 0.5, m_smoothFn, n, n-m_width, buf); } } } delete [] Di; delete [] (REAL *)buf; }