iVertexBuffer* cVertexBufferOGL::CreateCopy(eVertexBufferUsageType aUsageType) { cVertexBufferOGL *pVtxBuff = hplNew( cVertexBufferOGL,(mpLowLevelGraphics, mVertexFlags,mDrawType,aUsageType, GetVertexNum(),GetIndexNum()) ); //Copy the vertices to the new buffer. for(int i=0; i < klNumOfVertexFlags; i++) { if(kvVertexFlags[i] & mVertexFlags) { int lElements = kvVertexElements[i]; if(mbTangents && kvVertexFlags[i] == eVertexFlag_Texture1) lElements=4; pVtxBuff->ResizeArray(kvVertexFlags[i], (int)mvVertexArray[i].size()); memcpy(pVtxBuff->GetArray(kvVertexFlags[i]), &mvVertexArray[i][0], mvVertexArray[i].size() * sizeof(float)); } } //Copy indices to the new buffer pVtxBuff->ResizeIndices(GetIndexNum()); memcpy(pVtxBuff->GetIndices(), GetIndices(), GetIndexNum() * sizeof(unsigned int) ); pVtxBuff->mbTangents = mbTangents; pVtxBuff->mbHasShadowDouble = mbHasShadowDouble; pVtxBuff->Compile(0); return pVtxBuff; }
//****************************************************************************** //Name: SetTensor * // * //Purpose: Set the tensor portion of the field * // * //Takes: takes a pointer to a position array and the address of the tensor * //****************************************************************************** void field::SetTensor(double *position, const tensor &rval) { int *index; int *r_index; int i, j, temp; double value; //Error check if( rval.p->num_indices != (p->num_indices - 3) ) error("SetTensor error:","cannot assign a tensor to a field point"); for(i = 3; i < p->num_indices; i++) { if( rval.p->range[i-3] != p->range[i] ) error("SetTensor error:","cannot assign a tensor to a field point"); } //set up the index array that indexes into the field and set the specified position index = new int[p->num_indices]; GetIndices(position, index); //set up the index array that indexes into the rval tensor r_index = new int[rval.p->num_indices]; //create a tempory tensor for stupid Microsoft (comment out if not using MS) tensor temp_t; temp_t = rval; //set the field for(i = 0; i < rval.p->product; i++) { //pack the r_index array (see tensor::Contract) temp = 0; for(j = 0; j < rval.p->num_indices - 1; j++) { r_index[j] = (i - i%rval.p->scales[j] - temp)/rval.p->scales[j]; temp += r_index[j] * rval.p->scales[j]; } r_index[j] = (i - temp)/rval.p->scales[j]; //complete the index array with the tensor indices for(j = 3; j < p->num_indices; j++) index[j] = r_index[j - 3]; //comment out following line when using Microsoft (in the head) //value = rval.Val(r_index); //comment out following line when not using Microsoft (in the head) value = temp_t.Val(r_index); //put the rval tensors value into the field at specified position Set(value,index); } //Clean up delete [] index; delete [] r_index; }
// find the indices of the lattice element that contanis (x,y,z) int Lattice::GetIndices(float x, float y, float z, int &iidx, int &jidx, int &kidx) { int rank = GetRank(x,y,z); if (rank!=-1) { GetIndices(rank, iidx, jidx, kidx); return(rank); } else return(-1); }
int Lattice::CheckNeighbor(int myrank, float x, float y, float z) { int i,j,k; GetIndices(myrank, i, j, k); if (isIn(x,y,z,i-1,j,k)==true) return(0); //-X if (isIn(x,y,z,i+1,j,k)==true) return(1); //+X if (isIn(x,y,z,i,j-1,k)==true) return(2); //-Y if (isIn(x,y,z,i,j+1,k)==true) return(3); //+Y if (isIn(x,y,z,i,j,k-1)==true) return(4); //-Z if (isIn(x,y,z,i,j,k+1)==true) return(5); //+Z return(-1); }
bool UsdGeomPrimvar::ComputeFlattened(VtValue *value, UsdTimeCode time) const { VtValue attrVal; if (!Get(&attrVal, time)) { return false; } // If the primvar attr value is not an array or if the primvar isn't // indexed, simply return the attribute value. if (!attrVal.IsArrayValued() || !IsIndexed()) { *value = VtValue::Take(attrVal); return true; } VtIntArray indices; if (!GetIndices(&indices, time)) { TF_CODING_ERROR("No indices authored for indexed primvar <%s>.", _attr.GetPath().GetText()); return false; } // Handle all known supported array value types. bool foundSupportedType = _ComputeFlattenedArray<VtVec2fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtMatrix3dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtMatrix4dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtStringArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtDoubleArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtIntArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtFloatArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtHalfArray>(attrVal, indices, value); if (!foundSupportedType) { TF_WARN("Unsupported indexed primvar value type %s.", attrVal.GetTypeName().c_str()); } return !value->IsEmpty(); }
//------------------------------------------------------------------------------ /// \brief Gets the size necessary to read into a 1-dimensional array //------------------------------------------------------------------------------ int ArrayReaderParser::GetArraySize () const { int size = 1; if (ValidInputString()) { VEC_INT_PAIR indices = GetIndices(); for (size_t i = 0; i < indices.size(); ++i) { size *= indices[i].second; } } return size; } // ArrayReaderParser::GetArraySize
//****************************************************************************** //Name: SetInterpTensor * // * //Purpose: set the grid tensors based on interpolation from a tensor at an * // arbitrary position * // * //Takes: pointer to the position array and address of the rval tensor * //****************************************************************************** void field::SetInterpTensor(double *position, const tensor &rval) { int step; int i, j, k; int scaled_pos[3]; int grid_pos[3]; double pos[3]; tensor dummy, temp; step = 1; out_of_range = FALSE; //Set the reference position for(i = 0; i < 3; i++) reference_pos[i] = position[i]; //Get the double indices for the scaled position GetIndices(reference_pos, scaled_pos); //step through the floor steping while( !out_of_range ) { for( i = 0; i < 2; i++) { for( j = 0; j < 2; j++) { for( k = 0; k < 2; k++) { grid_pos[0] = (int)floor( scaled_pos[0] + i * step ); grid_pos[1] = (int)floor( scaled_pos[1] + j * step ); grid_pos[2] = (int)floor( scaled_pos[2] + k * step ); GetPosition(grid_pos, pos); dummy <= GetTensor(pos); temp <= rval; temp.ScalarMult(Smoother(PARTICLE_SMOOTHING)); dummy <= dummy + temp; if( out_of_range ) break; } } } //temp hack to keep the interpolation to within one cell out_of_range = TRUE; } }
void Init() { PROFILE_SCOPED() frac = 1.0 / double(edgeLen-1); // also want vtx indices for tris not touching edge of patch indices.reset(new unsigned short[IDX_VBO_COUNT_ALL_IDX()]); unsigned short *idx = indices.get(); for (int x=0; x<edgeLen-1; x++) { for (int y=0; y<edgeLen-1; y++) { idx[0] = x + edgeLen*y; idx[1] = x+1 + edgeLen*y; idx[2] = x + edgeLen*(y+1); idx+=3; idx[0] = x+1 + edgeLen*y; idx[1] = x+1 + edgeLen*(y+1); idx[2] = x + edgeLen*(y+1); idx+=3; } } // these will hold the optimised indices std::vector<unsigned short> pl_short; // populate the N indices lists from the arrays built during InitTerrainIndices() // iterate over each index list and optimize it unsigned int tri_count = GetIndices(pl_short); VertexCacheOptimizerUShort vco; VertexCacheOptimizerUShort::Result res = vco.Optimize(&pl_short[0], tri_count); assert(0 == res); //create buffer & copy indexBuffer.Reset(Pi::renderer->CreateIndexBuffer(pl_short.size(), Graphics::BUFFER_USAGE_STATIC)); Uint16* idxPtr = indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); for (Uint32 j = 0; j < pl_short.size(); j++) { idxPtr[j] = pl_short[j]; } indexBuffer->Unmap(); if (indices) { indices.reset(); } }
void CConvexHull::GetVertices(CArrayBlock* pasPositions, SFloat3* psPoints, int iStride) { CArrayInt aiIndices; int i; int iIndex; SFloat3* psPosition; aiIndices.Init(mcPolygons.NumElements()+1); GetIndices(&aiIndices, psPoints, iStride); for (i = 0; i < aiIndices.NumElements(); i++) { iIndex = aiIndices.GetValue(i); psPosition = GetPosition(psPoints, iStride, iIndex); pasPositions->Add(psPosition); } aiIndices.Kill(); }
VOID InsertWeight( DWORD dwIndex, DWORD dwBoneIndex, FLOAT fBoneWeight ) { assert( dwBoneIndex < 256 ); BYTE* pIndices = GetIndices( dwIndex ); FLOAT* pWeights = GetWeights( dwIndex ); for( DWORD i = 0; i < dwVertexStride; ++i ) { if( fBoneWeight > pWeights[i] ) { for( DWORD j = (dwVertexStride - 1); j > i; --j ) { pIndices[j] = pIndices[j - 1]; pWeights[j] = pWeights[j - 1]; } pIndices[i] = (BYTE)dwBoneIndex; pWeights[i] = fBoneWeight; break; } } }
_Use_decl_annotations_ Geometry AssetLoader::LoadGeometryFromFile(const char* filename) const { char source[MAX_PATH]; sprintf_s(source, "%s%s", GetConfig().ContentRoot, filename); GeometryFileData data; LoadGeometryFileData(source, &data); auto pool = GetGraphics().GetPoolWithSpace(VertexFormat::StaticGeometry, data.NumVertices, data.NumIndices); uint32_t verticesIndex = 0; uint32_t indicesIndex = 0; pool->ReserveRange(data.NumVertices, data.NumIndices, &verticesIndex, &indicesIndex); ComPtr<ID3D11Device> device; pool->GetVertices()->GetDevice(&device); ComPtr<ID3D11DeviceContext> context; device->GetImmediateContext(&context); D3D11_BOX box = {}; box.left = sizeof(StaticGeometryVertex) * verticesIndex; box.right = box.left + data.NumVertices * sizeof(StaticGeometryVertex); box.bottom = 1; box.back = 1; context->UpdateSubresource(pool->GetVertices(), 0, &box, data.Vertices, data.NumVertices * sizeof(StaticGeometryVertex), 0); box.left = sizeof(uint32_t) * indicesIndex; box.right = box.left + (data.NumIndices * sizeof(uint32_t)); context->UpdateSubresource(pool->GetIndices(), 0, &box, data.Indices, data.NumIndices * sizeof(uint32_t), 0); Geometry geometry(pool, verticesIndex, indicesIndex, data.NumIndices); FreeGeometryFileData(&data); return geometry; }
MyMeshText::MyMeshText(int maxletters, FontDefinition* pFont) { m_pFont = pFont; #if _DEBUG m_MostLettersAttemptedToDrawThisFrame = 0; m_MostLettersAttemptedToDrawEver = 0; #endif // Create buffers and base set of indices. CreateBuffers( VertexFormat_XYZUV_RGBA, (unsigned short)maxletters*4, maxletters*6, true ); unsigned short* pIndices = GetIndices( true ); for( unsigned short i=0; i<maxletters; i++ ) { pIndices[i*6+0] = i*4+0; // 0--1 pIndices[i*6+1] = i*4+2; // |\ | pIndices[i*6+2] = i*4+1; // | \| pIndices[i*6+3] = i*4+2; // 3--2 pIndices[i*6+4] = i*4+0; pIndices[i*6+5] = i*4+3; } RebuildIndices(); }
//****************************************************************************** //Name: GetInterpTensor * // * //Purpose: get the interpolated tensor at an arbitrary position * // * //Takes: pointer to the position array * //****************************************************************************** tensor field::GetInterpTensor(double *position) { int i, j, k, m, n; double scaled_pos[3]; int grid_pos[3]; double W; if( is_series_set == FALSE ) error("GetInterpTensor error:","series not set"); //initialize member data tensors sum_Wm <= 0.0*sum_Wm; sum_a2 <= 0.0*sum_a2; sum_da1 <= 0.0*sum_da1; d_sum_a2 <= 0.0*d_sum_a2; out_of_range = FALSE; //Set the reference position for(i = 0; i < 3; i++) reference_pos[i] = position[i]; //Get the real indices for the scaled position GetIndices(reference_pos, scaled_pos); //Create the return tensor and set it to zero ret_dummy <= 0.0*GetTensor(reference_pos); //Reset the normalization normalization = 0.0; //step through the floor steping for( i = grid_lower_bound; i < grid_upper_bound; i++) { for( j = grid_lower_bound; j < grid_upper_bound; j++) { for( k = grid_lower_bound; k < grid_upper_bound; k++) { //Get the indices of the lowest corner of the cell grid_pos[0] = (int)floor( scaled_pos[0] + i ); grid_pos[1] = (int)floor( scaled_pos[1] + j ); grid_pos[2] = (int)floor( scaled_pos[2] + k ); //find the position this grid point GetPosition(grid_pos,current_pos); //form the difference array and its magnitude (for use by smoother) //and the difference position y = 0; for( m = 0; m < 3; m++ ) { pos_diff[m] = reference_pos[m] - current_pos[m]; y += pos_diff[m]*pos_diff[m]; d.Set(pos_diff[m], m); } y = sqrt(y)/smoothing_length; if( y > 1.0 + SMOOTHING_TOL ) continue; //get all of the tensors requested by the order for( m = 0; m <= series.order; m++) tmp[m] <= series.list[m]->GetTensor(grid_pos); //get the (psuedo) scalar smoothing value W = Smoother(CWM_SMOOTHER); //if the field is basic (i.e. not a derivative of //another field) if( is_deriv_field == FALSE ) { if( series.order == 2 ) { m = tmp[2].NumIndices() - 1; tmp[2] <= 0.5 *( tmp[2].Contract(d,m,0) ).Contract(d,m-1,0); } if( series.order == 1 || series.order == 2 ) { m = tmp[1].NumIndices() - 1; tmp[1] <= tmp[1].Contract(d,m,0); } for( m = 0; m <= series.order; m++) ret_dummy <= ret_dummy + W*tmp[m]; } //if the field is not basic (i.e. is a derivative of //another field if( is_deriv_field == TRUE ) { //if the field is independent (i.e. its smoothing is not //a derivative of the smoohting of its basic field if( is_dep_field == FALSE ) { temp0 <= 0.0*tmp[0]; if( series.order == 1 ) { m = tmp[1].NumIndices() - 1; temp0 <= tmp[1].Contract(d,m,0); } ret_dummy <= ret_dummy + W*(tmp[0] + temp0); } //if the field is dependent (i.e. it smoothing is //based on the derivative of the smoothing of its basic field else { temp0 <= 0.0*tmp[0]; if( series.order == 2 ) { m = tmp[2].NumIndices() - 1; //form the 1/2 * t,ij*(z-x)_i*(z-x)_j term if neccessary temp0 <= 0.5*( tmp[2].Contract(d,m,0) ).Contract(d,m-1,0); } temp1 <= 0.0*tmp[0]; if( series.order ==1 || series.order == 2 ) { n = tmp[1].NumIndices() - 1; //form the t,i*(z-x)_i term if neccessary temp1 <= tmp[1].Contract(d,n,0); //form the t,i + t,ij*(z-x)_j temp2 <= 0.0*tmp[1]; if( series.order == 2 ) temp2 <= tmp[2].Contract(d,m,0); sum_da1 <= sum_da1 + W*(tmp[1] + temp2); } //form the t + t,i*(z-x)_i + 1/2 * t,ij*(z-x)_i*(z-x)_j a2 <= tmp[0] + temp1 + temp0; sum_a2 <= sum_a2 + W*a2; //get the derivative of the smoothing Wm <= Smoother_Deriv(CWM_SMOOTHER); //keep running sum sum_Wm <= sum_Wm + Wm; //form the term labeled dN_D_2 in the MathCAD d_sum_a2 <= d_sum_a2 + a2 * Wm; } } } } } //Normalize the interpolated tensor if( is_dep_field == FALSE ) ret_dummy <= (1.0/normalization)*ret_dummy; if( is_dep_field == TRUE ) { ret_dummy <= normalization * ( sum_da1 + d_sum_a2 ) - sum_a2 * sum_Wm; ret_dummy <= 1.0/(normalization*normalization) * ret_dummy; } return ret_dummy; }
//****************************************************************************** //Name: GetTensor * // * //Purpose: get the tensor portion of the field given the position * // * //Takes: point to a position array * //****************************************************************************** tensor field::GetTensor(double *position) { int *index; int num_indices, f_num_indices; int *range; int *d_index; int i, j, temp; //set up the index array that indexes into the field and pack the position indices index = new int[p->num_indices]; GetIndices(position, index); //get the parameters necessary to define the dummy return tensor num_indices = p->num_indices - 3; range = new int[num_indices]; for(i = 0; i < num_indices; i++) range[i] = p->range[i+3]; //set up the d_index array that indexes into the dummy return tensor d_index = new int[num_indices]; //Create the dummy tensor which will hold the return values and resize it tensor dummy; dummy.Resize(num_indices, range); //Loop over the number of components for(i = 0; i < dummy.p->product; i++) { //test for range = 1 cases here f_num_indices = p->num_indices; for(j = 0; j < p->num_indices; j++) { if(p->range[j] == 1) f_num_indices--; } //pack the index array (see tensor::Contract) temp = 0; for(j = 3; j < f_num_indices - 1; j++) { index[j] = (i - i%p->scales[j] - temp)/p->scales[j]; temp += index[j] * p->scales[j]; } //handle range = 1 cases here if(f_num_indices < p->num_indices) { index[f_num_indices - 1] = (i - temp)/p->scales[f_num_indices - 1]; for(j = f_num_indices; j < p->num_indices; j++) index[j] = 0; } else { index[j] = (i - temp)/p->scales[j]; } //strip off only the 'field' indices leaving the indices that specify position for(j = 0; j < num_indices; j++) d_index[j] = index[j+3]; //set the value of dummy with the value of the field dummy.Set(Val(index),d_index); } //clean up delete [] range; delete [] index; delete [] d_index; //return return dummy; }
BoundingBox::BoundingBox(btDiscreteDynamicsWorld* worldN) { world = worldN; layer = 0; parent = NULL; Vertex fill = { { -0.5f*METER, -0.5f*METER, -0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill); Vertex fill1 = { { 0.5f*METER, -0.5f*METER, 0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill1); Vertex fill2 = { { -0.5f*METER, -0.5f*METER, 0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill2); Vertex fill3 = { { 0.5f*METER, -0.5f*METER, -0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill3); Vertex fill4 = { { -0.5f*METER, 0.5f*METER, -0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill4); Vertex fill5 = { { 0.5f*METER, 0.5f*METER, 0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill5); Vertex fill6 = { { -0.5f*METER, 0.5f*METER, 0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill6); Vertex fill7 = { { 0.5f*METER, 0.5f*METER, -0.5f*METER }, { 1.0f, 0.0f, 0.0f } }; GetVertices().push_back(fill7); Index iFill1 = { glm::uvec3(0, 1, 2) }; GetIndices().push_back(iFill1); Index iFill2 = { glm::uvec3(0, 3, 1) }; GetIndices().push_back(iFill2); Index iFill3 = { glm::uvec3(4, 6, 5) }; GetIndices().push_back(iFill3); Index iFill4 = { glm::uvec3(4, 5, 7) }; GetIndices().push_back(iFill4); Index iFill5 = { glm::uvec3(0, 2, 6) }; GetIndices().push_back(iFill5); Index iFill6 = { glm::uvec3(0, 6, 4) }; GetIndices().push_back(iFill6); Index iFill7 = { glm::uvec3(1, 3, 7) }; GetIndices().push_back(iFill7); Index iFill8 = { glm::uvec3(1, 7, 5) }; GetIndices().push_back(iFill8); Index iFill9 = { glm::uvec3(0, 4, 7) }; GetIndices().push_back(iFill9); Index iFill10 = { glm::uvec3(0, 7, 3) }; GetIndices().push_back(iFill10); Index iFill11 = { glm::uvec3(1, 5, 6) }; GetIndices().push_back(iFill11); Index iFill12 = { glm::uvec3(1, 6, 2) }; GetIndices().push_back(iFill12); shape = new btBoxShape(btVector3(0.5f * METER, 0.5f * METER, 0.5f * METER)); btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50*METER, 0))); btScalar mass = 1; btVector3 fallInertia(0, 0, 0); shape->calculateLocalInertia(mass, fallInertia); btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, shape, fallInertia); rigidBody = new btRigidBody(fallRigidBodyCI); world->addRigidBody(rigidBody); Load(); }
//****************************************************************************** //Name: GetInterpTensor * // * //Purpose: get the interpolated tensor at an arbitrary position * // * //Takes: pointer to the position array * //****************************************************************************** tensor Particle::GetInterpTensor(double *position) { int i, j, k, m, n; double scaled_pos[3]; int grid_pos[3]; double W; //initialize member data tensors sum_Wm <= 0.0*sum_Wm; //Set the reference position for(i = 0; i < 3; i++) reference_pos[i] = position[i]; //Get the real indices for the scaled position GetIndices(reference_pos, scaled_pos); //Create the return tensor and set it to zero // ret_dummy <= 0.0*GetTensor(reference_pos); //Reset the normalization normalization = 0.0; //step through the floor steping for( i = grid_lower_bound; i < grid_upper_bound; i++) { for( j = grid_lower_bound; j < grid_upper_bound; j++) { for( k = grid_lower_bound; k < grid_upper_bound; k++) { //Get the indices of the lowest corner of the cell grid_pos[0] = (int)floor( scaled_pos[0] + i ); grid_pos[1] = (int)floor( scaled_pos[1] + j ); grid_pos[2] = (int)floor( scaled_pos[2] + k ); //find the position this grid point GetPosition(grid_pos,current_pos); //form the difference array and its magnitude (for use by smoother) //and the difference position y = 0; for( m = 0; m < 3; m++ ) { pos_diff[m] = reference_pos[m] - current_pos[m]; y += pos_diff[m]*pos_diff[m]; d.Set(pos_diff[m], m); } y = sqrt(y)/smoothing_length; if( y > 1.0 + SMOOTHING_TOL ) continue; //get the (psuedo) scalar smoothing value W = Smoother(CWM_SMOOTHER); //get the derivative of the smoothing Smoother_Deriv(CWM_SMOOTHER); //keep running sum sum_Wm <= sum_Wm + Wm; } } } //Normalize the interpolated tensor return ret_dummy;
//****************************************************************************** //Name: update_inv_g * // * //Purpose: scans over the relevant regions of the grid and gets a smoothed * // version of the inverse metric at the particle * // * //Takes: * //****************************************************************************** void Particle::update_inv_g(int stage) { int i, j, k, m, n; double scaled_pos[3]; int grid_pos[3]; double position[3]; double W; //loop over the particles and determine the smoothed inverse metric //for each one for( c1 = 0; c1 < numParticles; c1++) { //Set the reference position using the particle's position reference_pos[0] = pos[stage][c1].Val(0); reference_pos[1] = pos[stage][c1].Val(1); reference_pos[2] = pos[stage][c1].Val(2); //Get the real indices for the scaled position GetIndices(reference_pos, scaled_pos); //Reset the normalization normalization = 0.0; //initialize member data tensors sum_Wm <= 0.0*sum_Wm; T_temp4x4 <= 0.0*T_temp4x4; T_temp4x4x3 <= 0.0*T_temp4x4x3; //step through the floor steping for( i = grid_lower_bound; i < grid_upper_bound; i++) { for( j = grid_lower_bound; j < grid_upper_bound; j++) { for( k = grid_lower_bound; k < grid_upper_bound; k++) { //Get the indices of the lowest corner of the cell grid_pos[0] = (int)floor( scaled_pos[0] + i ); grid_pos[1] = (int)floor( scaled_pos[1] + j ); grid_pos[2] = (int)floor( scaled_pos[2] + k ); //find the metric at the particular grid point inv_g_temp <= my_field_partner->GetInvG(stage, grid_pos[0], grid_pos[1], grid_pos[2]); //find the position this grid point GetPosition(grid_pos,current_pos); //form the difference array and its magnitude (for use by smoother) //and the difference position y = 0; for( m = 0; m < 3; m++ ) { pos_diff[m] = reference_pos[m] - current_pos[m]; y += pos_diff[m]*pos_diff[m]; } y = sqrt(y)/smoothing_length; if( y > 1.0 + SMOOTHING_TOL ) continue; //get the (psuedo) scalar smoothing value W = Smoother(CWM_SMOOTHER); //get the derivative of the smoothing Smoother_Deriv(CWM_SMOOTHER); //keep running sum sum_Wm <= sum_Wm + Wm; T_temp4x4 <= T_temp4x4 + W*inv_g_temp; T_temp4x4x3 <= T_temp4x4x3 + inv_g_temp*Wm; } } } //Normalize the interpolated tensor and pack arrays inv_g[stage][c1] <= T_temp4x4; d_inv_g[stage][c1] <= T_temp4x4x3; norm[stage][c1] = normalization; d_norm[stage][c1] <= sum_Wm; }
void AasRenderer::Render(gfx::AnimatedModel *model, const gfx::AnimatedModelParams& params, gsl::span<Light3d> lights, const MdfRenderOverrides *materialOverrides) { // Find or create render caching data for the model auto &renderData = mRenderDataCache[model->GetHandle()]; if (!renderData) { renderData = std::make_unique<AasRenderData>(); } auto materialIds(model->GetSubmeshes()); for (size_t i = 0; i < materialIds.size(); ++i) { auto materialId = materialIds[i]; auto submesh(model->GetSubmesh(params, i)); // Remove special material marker in the upper byte and only // use the actual shader registration id materialId &= 0x00FFFFFF; // Usually this should not happen, since it means there's // an unbound replacement material if (materialId == 0) { continue; } // if material was not found if (materialId == 0x00FFFFFF) { continue; } auto material = mMdfFactory.GetById(materialId); if (!material) { logger->error("Legacy shader with id {} wasn't found.", materialId); continue; } material->Bind(mDevice, lights, materialOverrides); // Do we have to recalculate the normals? if (material->GetSpec()->recalculateNormals) { RecalcNormals( submesh->GetVertexCount(), submesh->GetPositions().data(), submesh->GetNormals().data(), submesh->GetPrimitiveCount(), submesh->GetIndices().data() ); } auto &submeshData = GetSubmeshData(*renderData, i, *submesh); submeshData.binding.Bind(); auto d3d = mDevice.GetDevice(); d3d->SetIndices(submeshData.idxBuffer->GetBuffer()); D3DLOG(d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, submesh->GetVertexCount(), 0, submesh->GetPrimitiveCount())); } }
void ModelDefinition::Serialize(Serializer &serializer) const { BasicSerializer intermediarySerializer; ///////////////////////////////////// // Bones intermediarySerializer.Write(static_cast<uint32_t>(m_bones.count)); // Local information. for (size_t iBone = 0; iBone < m_bones.count; ++iBone) { auto bone = m_bones[iBone]; assert(bone != nullptr); { // Name. intermediarySerializer.WriteString(bone->GetName()); // Relative transformation. intermediarySerializer.Write(bone->GetPosition()); intermediarySerializer.Write(bone->GetRotation()); intermediarySerializer.Write(bone->GetScale()); // 4x4 offset matrix. intermediarySerializer.Write(bone->GetOffsetMatrix()); } } // Parents. -1 for bones without parents. for (size_t iBone = 0; iBone < m_bones.count; ++iBone) { auto bone = m_bones[iBone]; assert(bone != nullptr); { auto parentBone = bone->GetParent(); if (parentBone != nullptr) { size_t parentBoneIndex; if (!this->FindBoneIndex(parentBone, parentBoneIndex)) { assert(false); } intermediarySerializer.Write(static_cast<uint32_t>(parentBoneIndex)); } else { intermediarySerializer.Write(static_cast<uint32_t>(-1)); } } } Serialization::ChunkHeader header; header.id = Serialization::ChunkID_Model_Bones; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Meshes // // Vertex data is always saved in P3T2N3T3B3 format. Bones are referenced using an integer to index into the list of bones defined above. intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(this->meshes.count)); for (size_t iMesh = 0; iMesh < this->meshes.count; ++iMesh) { // Name. intermediarySerializer.WriteString(this->meshes[iMesh].name); // Material. intermediarySerializer.WriteString(this->meshes[iMesh].material->GetDefinition().relativePath); // Vertices. auto vertexArray = this->meshes[iMesh].geometry; assert(vertexArray != nullptr); { // Vertex Format. vertexArray->GetFormat().Serialize(intermediarySerializer); // Vertices. intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount())); if (vertexArray->GetVertexCount() > 0) { intermediarySerializer.Write(vertexArray->GetVertexDataPtr(), vertexArray->GetFormat().GetSizeInBytes() * vertexArray->GetVertexCount()); } // Indices. intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetIndexCount())); if (vertexArray->GetIndexCount() > 0) { intermediarySerializer.Write(vertexArray->GetIndexDataPtr(), sizeof(uint32_t) * vertexArray->GetIndexCount()); } // Skinning Vertex Attributes. if (this->meshes[iMesh].skinningVertexAttributes != nullptr) { intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount())); if (vertexArray->GetVertexCount() > 0) { uint32_t totalBoneWeights = 0; // Bone Counts. for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex) { uint16_t count = static_cast<uint16_t>(this->meshes[iMesh].skinningVertexAttributes[iVertex].bones.count); intermediarySerializer.Write(count); totalBoneWeights += count; } // Bone/Weight Pairs. intermediarySerializer.Write(totalBoneWeights); for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex) { auto &bones = this->meshes[iMesh].skinningVertexAttributes[iVertex].bones; { for (size_t iBone = 0; iBone < bones.count; ++iBone) { auto &bone = bones[iBone]; intermediarySerializer.Write(static_cast<uint32_t>(bone.boneIndex)); intermediarySerializer.Write(static_cast<float >(bone.weight)); } } } } } else { intermediarySerializer.Write(static_cast<uint32_t>(0)); } // Default uniforms. this->meshes[iMesh].defaultUniforms.Serialize(intermediarySerializer); } } header.id = Serialization::ChunkID_Model_Meshes; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetKeyFrameCount())); for (uint32_t iKeyFrame = 0; iKeyFrame < m_animation.GetKeyFrameCount(); ++iKeyFrame) { // Time. intermediarySerializer.Write(static_cast<float>(m_animation.GetKeyFrameTimeByIndex(iKeyFrame))); // Channels. intermediarySerializer.Write(static_cast<uint32_t>(this->animationChannelBones.count)); for (size_t iChannel = 0; iChannel < this->animationChannelBones.count; ++iChannel) { auto channel = this->animationChannelBones.buffer[iChannel]->value; auto bone = this->animationChannelBones.buffer[iChannel]->key; assert(channel != nullptr); assert(bone != nullptr); { // Bone Index. size_t boneIndex; this->FindBoneIndex(bone, boneIndex); intermediarySerializer.Write(static_cast<uint32_t>(boneIndex)); // Bone Transformation. glm::vec3 position; glm::quat rotation; glm::vec3 scale; auto key = static_cast<TransformAnimationKey*>(channel->GetKey(iKeyFrame)); if (key != nullptr) { position = key->position; rotation = key->rotation; scale = key->scale; } else { // We should never actually get here, but for completeness we'll just write identities. position = bone->GetPosition(); rotation = bone->GetRotation(); scale = bone->GetScale(); } intermediarySerializer.Write(position); intermediarySerializer.Write(rotation); intermediarySerializer.Write(scale); } } } intermediarySerializer.Write(this->animationAABBPadding); header.id = Serialization::ChunkID_Model_Animation; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation Segments intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetNamedSegmentCount())); for (size_t iSegment = 0; iSegment < m_animation.GetNamedSegmentCount(); ++iSegment) { auto segment = m_animation.GetNamedSegmentByIndex(iSegment); assert(segment != nullptr); { intermediarySerializer.WriteString(segment->name); intermediarySerializer.Write(static_cast<uint32_t>(segment->startKeyFrame)); intermediarySerializer.Write(static_cast<uint32_t>(segment->endKeyFrame)); } } header.id = Serialization::ChunkID_Model_AnimationSegments; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation Sequences /* intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(this->animationSequences.count)); for (size_t iSequence = 0; iSequence < this->animationSequences.count; ++iSequence) { } header.id = Serialization::ChunkID_Model_AnimationSequences; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); */ ///////////////////////////////////// // Convex Hulls intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_convexHulls.count)); Vector<uint32_t> vertexCounts(m_convexHulls.count); Vector<uint32_t> indexCounts( m_convexHulls.count); Vector<float> vertices; Vector<uint32_t> indices; for (size_t iConvexHull = 0; iConvexHull < m_convexHulls.count; ++iConvexHull) { auto convexHull = m_convexHulls[iConvexHull]; assert(convexHull != nullptr); { uint32_t vertexCount = static_cast<uint32_t>(convexHull->GetVertexCount()); uint32_t indexCount = static_cast<uint32_t>(convexHull->GetIndexCount()); vertexCounts.PushBack(vertexCount); indexCounts.PushBack( indexCount); for (uint32_t iVertex = 0; iVertex < vertexCount; ++iVertex) { vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 0]); vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 1]); vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 2]); } for (uint32_t iIndex = 0; iIndex < indexCount; ++iIndex) { indices.PushBack(convexHull->GetIndices()[iIndex]); } } } intermediarySerializer.Write(vertexCounts.buffer, vertexCounts.count * 4); intermediarySerializer.Write(indexCounts.buffer, indexCounts.count * 4); intermediarySerializer.Write(static_cast<uint32_t>(vertices.count)); intermediarySerializer.Write(static_cast<uint32_t>(indices.count)); intermediarySerializer.Write(vertices.buffer, vertices.count * 4); intermediarySerializer.Write(indices.buffer, indices.count * 4); intermediarySerializer.Write(this->convexHullBuildSettings); header.id = Serialization::ChunkID_Model_ConvexHulls; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Null Chunk header.id = Serialization::ChunkID_Null; header.version = 1; header.sizeInBytes = 0; serializer.Write(header); }