int FifoStream::write(const void* buffer, int size) { int maxWrite = 0; if (m_writing <= m_reading) maxWrite = (m_reading-m_writing)-1; else maxWrite = ((m_reading+m_buffer.count())-m_writing)-1; if (maxWrite < size) { DataPtr<u8> newData; // TODO: resize 2^x to allow for efficient performance newData.allocate(m_buffer.count() + (size-maxWrite)); if (m_reading <= m_writing) { ::memcpy(newData.objects(), &m_buffer.objects()[m_reading], m_writing-m_reading); m_writing -= m_reading; m_reading = 0; } else { // INCORRECT! ::memcpy(newData.objects(), m_buffer.objects() + m_reading, m_buffer.count()-m_reading); ::memcpy(newData.objects() + (m_buffer.count()-m_reading), m_buffer.objects(), m_writing); m_writing = m_reading-m_writing; m_reading = 0; } m_buffer.free(); m_buffer = newData; } int actualWrite = size; const char* currentBuffer = static_cast<const char*>(buffer); while (size > 0) { int currentWrite = size; if (uint(m_writing + currentWrite) > m_buffer.count()) currentWrite = m_buffer.count() - m_writing; ::memcpy(m_buffer.objects() + m_writing, currentBuffer, currentWrite); m_writing += currentWrite; if (m_buffer.count() == uint(m_writing)) m_writing = 0; currentBuffer += currentWrite; size -= currentWrite; } return actualWrite; }
Serializable* ExporterBackend::buildTexture(CSLImage* image, CSIBCPixMap& pixMap) { uint depth = pixMap.GetTotalPixelDepthByte(); // We only handly 32 bit and 24bit textures right now if (depth != 4 && depth != 3) { ZENIC_WARNING("Unsupported pixeldepth (" << pixMap.GetTotalPixelDepthByte() << ") for texture " << image->GetSourceFile() << "skipping"); return 0; } Texture* texture = zenic_new Texture; TextureData* textureData = zenic_new TextureData; textureData->setWidth(u16(pixMap.GetWidth())); textureData->setHeight(u16(pixMap.GetHeight())); textureData->setFlags(TextureData::RGB); DataPtr<u8> imageData; uint imageSize = pixMap.GetWidth() * pixMap.GetHeight() * depth; imageData.allocate(imageSize); memcpy(imageData.objects(), pixMap.GetMap(), imageSize); textureData->setImageData(imageData); texture->setData(textureData); return texture; }
zenic::ModelData* ExporterBackend::buildModelData(CSLModel* model, Model* modelNode) { ModelData* target = zenic_new ModelData; CSLXSIMesh* mesh = static_cast<CSLXSIMesh*>(model->Primitive()); CSLXSIShape* shape = mesh->XSIShape(); DegenerateMesh degMesh; degMesh.process(mesh); TriangleStrip triangleStripper(TriangleStrip::Actc); const TriangleStrip::StripInfo& stripInfo = triangleStripper.process(°Mesh); if (stripInfo.remapTable == 0) { ZENIC_ERROR("Failed to trianglestrip " << mesh->GetName() << " mesh will be skipped"); zenic_delete target; return 0; } // Set the correct material to the modelData if (model->GlobalMaterial()) target->setMaterial((opengl::Material*)findMaterial(model->GlobalMaterial()->GetMaterial())); SkinInfo* skinInfo = 0; if (model->GetEnvelopeCount() != 0) { skinInfo = buildSkinInfo(model, modelNode, stripInfo.remapTable); target->setType(ModelData::Skinned); } static float colors[] = { 0, 1.0f, 1.0f, 0, 1.0f, 0, 1.0f, 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 0, 0 }; target->polygons().allocate(u32(stripInfo.stripList.size())); ModelData::PolygonList* polygonLists = target->polygons().objects(); const std::vector<DegenerateMesh::Vertex>& vertices = degMesh.vertexList(); uint d = 0; for (std::vector<DataPtr<u32>*>::const_iterator i = stripInfo.stripList.begin(); i != stripInfo.stripList.end(); ++i, ++d) { u32 colorSelection = (d & 3) << 2; DataPtr<u32>* triStripList = (*i); // process strip u32* stripList = triStripList->objects(); u32 stripCount = triStripList->count(); ModelData::PolygonList& polygonList = polygonLists[d]; polygonList.setPolygonType(ModelData::TriStrips); if (skinInfo) polygonList.setVertexFormat(ModelData::Postion | ModelData::Color | ModelData::Weight); else polygonList.setVertexFormat(ModelData::Postion | ModelData::Color | ModelData::Uv1); if (skinInfo) polygonList.vertexStream().allocate((stripCount * 14)); // coords and colors else polygonList.vertexStream().allocate((stripCount * 8)); // 3 coords, 3 colors, 2 uv f32* tempStream = polygonList.vertexStream().objects(); for (uint d = 0; d < stripCount; ++d) { const DegenerateMesh::Vertex& vertex = vertices[stripList[d]]; *tempStream++ = vertex.position.x; *tempStream++ = vertex.position.y; *tempStream++ = vertex.position.z; *tempStream++ = colors[colorSelection + 0]; *tempStream++ = colors[colorSelection + 1]; *tempStream++ = colors[colorSelection + 2]; *tempStream++ = vertex.uv.x; *tempStream++ = vertex.uv.y; if (skinInfo) { const SkinInfo& currInfo = skinInfo[stripList[d]]; for (uint d = 0; d < 4; ++d) { *tempStream++ = float(currInfo.indices[d]); *tempStream++ = float(currInfo.weights[d]); } } } } delete [] skinInfo; return target; }