void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList& buckets, vector<sortedmeshslot>& slots, bool alpha) { BucketList::iterator bit; list<RAS_MeshSlot>::iterator mit; size_t size = 0, i = 0; /* Camera's near plane equation: pnorm.dot(point) + pval, * but we leave out pval since it's constant anyway */ const MT_Vector3 pnorm(cameratrans.getBasis()[2]); for (bit = buckets.begin(); bit != buckets.end(); ++bit) { SG_DList::iterator<RAS_MeshSlot> mit((*bit)->GetActiveMeshSlots()); for(mit.begin(); !mit.end(); ++mit) size++; } slots.resize(size); for (bit = buckets.begin(); bit != buckets.end(); ++bit) { RAS_MaterialBucket* bucket = *bit; RAS_MeshSlot* ms; // remove the mesh slot form the list, it culls them automatically for next frame while((ms = bucket->GetNextActiveMeshSlot())) { slots[i++].set(ms, bucket, pnorm); } } if(alpha) sort(slots.begin(), slots.end(), backtofront()); else sort(slots.begin(), slots.end(), fronttoback()); }
void RAS_MeshObject::SortPolygons(RAS_MeshSlot& ms, const MT_Transform &transform) { // Limitations: sorting is quite simple, and handles many // cases wrong, partially due to polygons being sorted per // bucket. // // a) mixed triangles/quads are sorted wrong // b) mixed materials are sorted wrong // c) more than 65k faces are sorted wrong // d) intersecting objects are sorted wrong // e) intersecting polygons are sorted wrong // // a) can be solved by making all faces either triangles or quads // if they need to be z-sorted. c) could be solved by allowing // larger buckets, b) and d) cannot be solved easily if we want // to avoid excessive state changes while drawing. e) would // require splitting polygons. RAS_MeshSlot::iterator it; size_t j; for (ms.begin(it); !ms.end(it); ms.next(it)) { unsigned int nvert = (int)it.array->m_type; unsigned int totpoly = it.totindex/nvert; if (totpoly <= 1) continue; if (it.array->m_type == RAS_DisplayArray::LINE) continue; // Extract camera Z plane... const MT_Vector3 pnorm(transform.getBasis()[2]); // unneeded: const MT_Scalar pval = transform.getOrigin()[2]; vector<polygonSlot> poly_slots(totpoly); /* get indices and z into temporary array */ for (j=0; j<totpoly; j++) poly_slots[j].get(it.vertex, it.index, j*nvert, nvert, pnorm); /* sort (stable_sort might be better, if flickering happens?) */ std::sort(poly_slots.begin(), poly_slots.end(), backtofront()); /* get indices from temporary array again */ for (j=0; j<totpoly; j++) poly_slots[j].set(it.index, j*nvert, nvert); } }
void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, RAS_BucketManager::BucketType bucketType, std::vector<sortedmeshslot>& slots, bool alpha, RAS_IRasterizer *rasty) { const unsigned int size = GetNumActiveMeshSlots(bucketType); // Discard if there's no mesh slots. if (size == 0) { return; } size_t i = 0; /* Camera's near plane equation: pnorm.dot(point) + pval, * but we leave out pval since it's constant anyway */ const MT_Vector3 pnorm(cameratrans.getBasis()[2]); slots.resize(size); BucketList& buckets = m_buckets[bucketType]; for (BucketList::iterator bit = buckets.begin(); bit != buckets.end(); ++bit) { RAS_MaterialBucket *bucket = *bit; RAS_DisplayArrayBucketList& displayArrayBucketList = (*bit)->GetDisplayArrayBucketList(); for (RAS_DisplayArrayBucketList::iterator dbit = displayArrayBucketList.begin(), dbend = displayArrayBucketList.end(); dbit != dbend; ++dbit) { RAS_DisplayArrayBucket *displayArrayBucket = *dbit; RAS_MeshSlotList& activeMeshSlots = displayArrayBucket->GetActiveMeshSlots(); // Update deformer and render settings. displayArrayBucket->UpdateActiveMeshSlots(rasty); for (RAS_MeshSlotList::iterator it = activeMeshSlots.begin(), end = activeMeshSlots.end(); it != end; ++it) { slots[i++].set(*it, bucket, pnorm); } displayArrayBucket->RemoveActiveMeshSlots(); } } if (alpha) sort(slots.begin(), slots.end(), backtofront()); else sort(slots.begin(), slots.end(), fronttoback()); }