示例#1
0
void export_multistream_avi_info_attr(
	media_multistream_format::avi_info f,
	ExportContext& context) {

	context.writeAttr(gKey_us_per_frame, f.us_per_frame);
	context.writeAttr(gKey_width, (uint32)f.width);
	context.writeAttr(gKey_height, (uint32)f.height);
}
示例#2
0
void export_raw_video_content(
	const media_raw_video_format& f,
	ExportContext& context) {
	
	context.beginContent();
	context.beginElement(MediaFormatIO::s_video_display_info_tag);
	export_video_display_info_attr(f.display, context);
	context.endElement();
}
示例#3
0
void export_encoded_video_content(
	const media_encoded_video_format& f,
	ExportContext& context) {

	context.beginContent();

	context.beginElement(MediaFormatIO::s_raw_video_tag);
	export_raw_video_attr(f.output, context);
	context.endElement();
}
示例#4
0
// -------------------------------------------------------- //
void ConnectionIO::xmlExportBegin(
    ExportContext&						context) const {

    if(!m_exportValid) {
        context.reportError(
            "ConnectionIO::xmlExportBegin():\n"
            "*** invalid ***\n");
        return;
    }

    context.beginElement(_CONNECTION_ELEMENT);
}
示例#5
0
void export_multistream_flags_attr(
	uint32 flags,
	ExportContext& context) {

	if(flags & media_multistream_format::B_HEADER_HAS_FLAGS)
		context.writeAttr(gKey_header_has_flags, (int32)1);

	if(flags & media_multistream_format::B_CLEAN_BUFFERS)
		context.writeAttr(gKey_clean_buffers, (int32)1);

	if(flags & media_multistream_format::B_HOMOGENOUS_BUFFERS)
		context.writeAttr(gKey_homogenous_buffers, (int32)1);
}
示例#6
0
void export_raw_video_attr(
	const media_raw_video_format& f,
	ExportContext& context) {

	media_raw_video_format& w = media_raw_video_format::wildcard;

	// attributes
	if(f.field_rate != w.field_rate)
		context.writeAttr(gKey_field_rate, f.field_rate);	
	if(f.interlace != w.interlace)
		context.writeAttr(gKey_interlace, f.interlace);	
	if(f.first_active != w.first_active)
		context.writeAttr(gKey_first_active, f.first_active);	
	if(f.last_active != w.last_active)
		context.writeAttr(gKey_last_active, f.last_active);	
	if(f.pixel_width_aspect != w.pixel_width_aspect)
		context.writeAttr(gKey_pixel_width_aspect, (uint32)f.pixel_width_aspect);	
	if(f.pixel_height_aspect != w.pixel_height_aspect)
		context.writeAttr(gKey_pixel_height_aspect, (uint32)f.pixel_height_aspect);	

	switch(f.orientation) {
		case B_VIDEO_TOP_LEFT_RIGHT:
			context.writeAttr(gKey_orientation, "B_VIDEO_TOP_LEFT_RIGHT");
			break;
		case B_VIDEO_BOTTOM_LEFT_RIGHT:
			context.writeAttr(gKey_orientation, "B_VIDEO_BOTTOM_LEFT_RIGHT");
			break;
		default:
			break;
	}
}
示例#7
0
void export_multistream_content(
	const media_multistream_format& f,
	ExportContext& context) {

	context.beginContent();
	
	// write flags
	context.beginElement(MediaFormatIO::s_multistream_flags_tag);
	export_multistream_flags_attr(f.flags, context);
	context.endElement();
	
	// write format-specific info
	if(f.format == media_multistream_format::B_VID) {
		context.beginElement(MediaFormatIO::s_multistream_vid_info_tag);
		export_multistream_vid_info_attr(f.u.vid, context);
		context.endElement();
	}
	else if(f.format == media_multistream_format::B_AVI) {
		context.beginElement(MediaFormatIO::s_multistream_avi_info_tag);
		export_multistream_avi_info_attr(f.u.avi, context);
		context.beginContent();
		export_multistream_avi_info_content(f.u.avi, context);
		context.endElement();
	}
}
示例#8
0
void export_encoded_audio_content(
	const media_encoded_audio_format& f,
	ExportContext& context) {
	
	context.beginContent();

	context.beginElement(MediaFormatIO::s_raw_audio_tag);
	export_raw_audio_attr(f.output, context);

#if B_BEOS_VERSION > B_BEOS_VERSION_4_5
	export_multi_audio_info_attr(f.multi_info, context);
#endif

	context.endElement();
}
示例#9
0
void export_multi_audio_info_attr(
	const media_multi_audio_info& f,
	ExportContext& context) {

	media_multi_audio_format& w = media_multi_audio_format::wildcard;

	if(f.channel_mask != w.channel_mask)
		context.writeAttr(gKey_channel_mask, f.channel_mask);

	if(f.valid_bits != w.valid_bits)
		context.writeAttr(gKey_valid_bits, f.valid_bits);

	if(f.matrix_mask != w.matrix_mask)
		context.writeAttr(gKey_matrix_mask, f.matrix_mask);
}
示例#10
0
void export_multistream_avi_info_content(
	media_multistream_format::avi_info f,
	ExportContext& context) {

	context.beginContent();
		
	for(uint16 n = 0; n < f.type_count; ++n)
		write_media_type(f.types[n], context);
}
示例#11
0
__USE_CORTEX_NAMESPACE

// -------------------------------------------------------- //
// EXPORT [not implemented]
// -------------------------------------------------------- //

void StringContent::xmlExportBegin(
	ExportContext&								context) const {
	context.reportError("StringContent: no export");
}	
示例#12
0
void FlatMessageIO::xmlExportContent(
	ExportContext& context) const {

	context.beginContent();

	// convert message to base64
	ASSERT(m_message);
	ssize_t flatSize = m_message->FlattenedSize();
	ASSERT(flatSize);
	char* flatData = new char[flatSize];
	status_t err = m_message->Flatten(flatData, flatSize);
	ASSERT(err == B_OK);
	
	// make plenty of room for encoded content (encode_base64 adds newlines)
	ssize_t base64Size = ((flatSize * 3) / 2);
	char* base64Data = new char[base64Size];
	ssize_t base64Used = encode_base64(base64Data, flatData, flatSize);
	base64Data[base64Used] = '\0';
	
	// write the data

	const char* pos = base64Data;
	while(*pos) {
		ssize_t chunk = 0;
		const char* nextBreak = strchr(pos, '\n');
		if(!nextBreak)
			chunk = strlen(pos);
		else
			chunk = nextBreak - pos;

		context.writeString(context.indentString());
		context.writeString(pos, chunk);
		context.writeString("\n");
		
		pos += chunk;
		if(*pos == '\n')
			++pos;
	}
	
	// clean up
	delete [] flatData;
	delete [] base64Data;
}
示例#13
0
void export_video_display_info_attr(
	const media_video_display_info& d,
	ExportContext& context) {

	media_video_display_info& w = media_video_display_info::wildcard;
	
	if(d.line_width != w.line_width)
		context.writeAttr(gKey_line_width, d.line_width);
	if(d.line_count != w.line_count)
		context.writeAttr(gKey_line_count, d.line_count);
	if(d.bytes_per_row != w.bytes_per_row)
		context.writeAttr(gKey_bytes_per_row, d.bytes_per_row);
	if(d.pixel_offset != w.pixel_offset)
		context.writeAttr(gKey_pixel_offset, d.pixel_offset);
	if(d.line_offset != w.line_offset)
		context.writeAttr(gKey_line_offset, d.line_offset);

	if(d.format != w.format)
		write_colorspace_attr(gKey_format, d.format, context);
}
示例#14
0
void export_encoded_audio_attr(
	const media_encoded_audio_format& f,
	ExportContext& context) {
	
	media_encoded_audio_format& w = media_encoded_audio_format::wildcard;

	switch(f.encoding) {
		case media_encoded_audio_format::B_ANY:
			context.writeAttr(gKey_encoding, "B_ANY");
			break;
		default:
			break;
	}

	if(f.bit_rate != w.bit_rate)
		context.writeAttr(gKey_bit_rate, f.bit_rate);

	if(f.frame_size != w.frame_size)
		context.writeAttr(gKey_frame_size, f.frame_size);
}
示例#15
0
void export_encoded_video_attr(
	const media_encoded_video_format& f,
	ExportContext& context) {

	media_encoded_video_format& w = media_encoded_video_format::wildcard;

	switch(f.encoding) {
		case media_encoded_video_format::B_ANY:
			context.writeAttr(gKey_encoding, "B_ANY");
			break;
		default:
			break;
	}

	if(f.avg_bit_rate != w.avg_bit_rate)
		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
	if(f.max_bit_rate != w.max_bit_rate)
		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
	if(f.frame_size != w.frame_size)
		context.writeAttr(gKey_frame_size, f.frame_size);
	if(f.forward_history != w.forward_history)
		context.writeAttr(gKey_forward_history, (int32)f.forward_history);
	if(f.backward_history != w.backward_history)
		context.writeAttr(gKey_backward_history, (int32)f.backward_history);
}
示例#16
0
void MediaFormatIO::xmlExportBegin(
	ExportContext&		context) const {
	
	switch(m_format.type) {

		case B_MEDIA_RAW_AUDIO:
			context.beginElement(s_raw_audio_tag);
			break;
		
		case B_MEDIA_RAW_VIDEO:
			context.beginElement(s_raw_video_tag);
			break;
			
		case B_MEDIA_MULTISTREAM:
			context.beginElement(s_multistream_tag);
			break;
			
		case B_MEDIA_ENCODED_AUDIO:
			context.beginElement(s_encoded_audio_tag);
			break;
			
		case B_MEDIA_ENCODED_VIDEO:
			context.beginElement(s_encoded_video_tag);
			break;
			
		default:
			// +++++ not very polite
			context.reportError("MediaFormatIO: type not supported\n");
			break;
	}	
}
示例#17
0
void RouteAppNodeManager::xmlExportBegin(
	ExportContext&								context) const {

	status_t err;
	
	try {
		NodeSetIOContext& set = dynamic_cast<NodeSetIOContext&>(context);
		context.beginElement(_NODE_SET_ELEMENT);
		
		// validate the node set
		for(int n = set.countNodes()-1; n >= 0; --n) {
			media_node_id id = set.nodeAt(n);
			ASSERT(id != media_node::null.node);
			
			// fetch node
			NodeRef* ref;
			err = getNodeRef(id, &ref);
			if(err < B_OK) {
				D_SETTINGS((
					"! RVNM::xmlExportBegin(): node %ld doesn't exist\n", id));

				set.removeNodeAt(n);
				continue;
			}
			// skip unless internal
			if(!ref->isInternal()) {
				D_SETTINGS((
					"! RVNM::xmlExportBegin(): node %ld not internal; skipping.\n", id));

				set.removeNodeAt(n);
				continue;
			}
		}
	}
	catch(bad_cast& e) {
		context.reportError("RouteAppNodeManager: expected a NodeSetIOContext\n");
	}
}
示例#18
0
void export_raw_audio_attr(
	const media_raw_audio_format& f,
	ExportContext& context) {

	media_raw_audio_format& w = media_raw_audio_format::wildcard;

	if(f.frame_rate != w.frame_rate)
		context.writeAttr(gKey_frame_rate, f.frame_rate);	
	if(f.channel_count != w.channel_count)
		context.writeAttr(gKey_channel_count, f.channel_count);
	if(f.buffer_size != w.buffer_size)
		context.writeAttr(gKey_buffer_size, f.buffer_size);

	switch(f.format) {
		case media_raw_audio_format::B_AUDIO_UCHAR:
			context.writeAttr(gKey_format, "B_AUDIO_UCHAR");
			break;
		case media_raw_audio_format::B_AUDIO_SHORT:
			context.writeAttr(gKey_format, "B_AUDIO_SHORT");
			break;
		case media_raw_audio_format::B_AUDIO_FLOAT:
			context.writeAttr(gKey_format, "B_AUDIO_FLOAT");
			break;
		case media_raw_audio_format::B_AUDIO_INT:
			context.writeAttr(gKey_format, "B_AUDIO_INT");
			break;
		default:
			break;
	}
	
	switch(f.byte_order) {
		case B_MEDIA_BIG_ENDIAN:
			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
			break;
		case B_MEDIA_LITTLE_ENDIAN:
			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
			break;
		default:
			break;
	}
}
示例#19
0
void export_multistream_attr(
	const media_multistream_format& f,
	ExportContext& context) {
	
	media_multistream_format& w = media_multistream_format::wildcard;

	// attributes
	switch(f.format) {
		case media_multistream_format::B_ANY:
			context.writeAttr(gKey_multistream_format, "B_ANY");
			break;
		case media_multistream_format::B_VID:
			context.writeAttr(gKey_multistream_format, "B_VID");
			break;
		case media_multistream_format::B_AVI:
			context.writeAttr(gKey_multistream_format, "B_AVI");
			break;
		case media_multistream_format::B_MPEG1:
			context.writeAttr(gKey_multistream_format, "B_MPEG1");
			break;
		case media_multistream_format::B_MPEG2:
			context.writeAttr(gKey_multistream_format, "B_MPEG2");
			break;
		case media_multistream_format::B_QUICKTIME:
			context.writeAttr(gKey_multistream_format, "B_QUICKTIME");
			break;
		default:
			if(f.format != w.format) {
				// write numeric value
				context.writeAttr(gKey_multistream_format, f.format);
			}
			break;
	}

	if(f.avg_bit_rate != w.avg_bit_rate)
		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
	if(f.max_bit_rate != w.max_bit_rate)
		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
	if(f.avg_chunk_size != w.avg_chunk_size)
		context.writeAttr(gKey_avg_chunk_size, f.avg_chunk_size);
	if(f.max_chunk_size != w.max_chunk_size)
		context.writeAttr(gKey_max_chunk_size, f.max_chunk_size);
}
示例#20
0
void MediaFormatIO::xmlExportEnd(
	ExportContext&		context) const {

	context.endElement();
}
示例#21
0
void StringContent::xmlExportEnd(
	ExportContext&								context) const {
	context.reportError("StringContent: no export");
}
示例#22
0
void NodeKey::xmlExportEnd(
	ExportContext&								context) const {
	context.endElement();
}
示例#23
0
void write_colorspace_attr(
	const char* key,
	color_space c,
	ExportContext& context) {
	
	switch(c) {
		case B_RGB32:
			context.writeAttr(key, "B_RGB32");
			break;
		case B_RGBA32:
			context.writeAttr(key, "B_RGBA32");
			break;
		case B_RGB24:
			context.writeAttr(key, "B_RGB24");
			break;
		case B_RGB16:
			context.writeAttr(key, "B_RGB16");
			break;
		case B_RGB15:
			context.writeAttr(key, "B_RGB15");
			break;
		case B_RGBA15:
			context.writeAttr(key, "B_RGBA15");
			break;
		case B_CMAP8:
			context.writeAttr(key, "B_CMAP8");
			break;
		case B_GRAY8:
			context.writeAttr(key, "B_GRAY8");
			break;
		case B_GRAY1:
			context.writeAttr(key, "B_GRAY1");
			break;
		case B_RGB32_BIG:
			context.writeAttr(key, "B_RGB32_BIG");
			break;
		case B_RGBA32_BIG:
			context.writeAttr(key, "B_RGBA32_BIG");
			break;
		case B_RGB24_BIG:
			context.writeAttr(key, "B_RGB24_BIG");
			break;
		case B_RGB16_BIG:
			context.writeAttr(key, "B_RGB16_BIG");
			break;
		case B_RGB15_BIG:
			context.writeAttr(key, "B_RGB15_BIG");
			break;
		case B_RGBA15_BIG:
			context.writeAttr(key, "B_RGBA15_BIG");
			break;
		case B_YCbCr422:
			context.writeAttr(key, "B_YCbCr422");
			break;
		case B_YCbCr411:
			context.writeAttr(key, "B_YCbCr411");
			break;
		case B_YCbCr444:
			context.writeAttr(key, "B_YCbCr444");
			break;
		case B_YCbCr420:
			context.writeAttr(key, "B_YCbCr420");
			break;
		case B_YUV422:
			context.writeAttr(key, "B_YUV422");
			break;
		case B_YUV411:
			context.writeAttr(key, "B_YUV411");
			break;
		case B_YUV444:
			context.writeAttr(key, "B_YUV444");
			break;
		case B_YUV420:
			context.writeAttr(key, "B_YUV420");
			break;
		case B_YUV9:
			context.writeAttr(key, "B_YUV9");
			break;
		case B_YUV12:
			context.writeAttr(key, "B_YUV12");
			break;
		case B_UVL24:
			context.writeAttr(key, "B_UVL24");
			break;
		case B_UVL32:
			context.writeAttr(key, "B_UVL32");
			break;
		case B_UVLA32:
			context.writeAttr(key, "B_UVLA32");
			break;
		case B_LAB24:
			context.writeAttr(key, "B_LAB24");
			break;
		case B_LAB32:
			context.writeAttr(key, "B_LAB32");
			break;
		case B_LABA32:
			context.writeAttr(key, "B_LABA32");
			break;
		case B_HSI24:
			context.writeAttr(key, "B_HSI24");
			break;
		case B_HSI32:
			context.writeAttr(key, "B_HSI32");
			break;
		case B_HSIA32:
			context.writeAttr(key, "B_HSIA32");
			break;
		case B_HSV24:
			context.writeAttr(key, "B_HSV24");
			break;
		case B_HSV32:
			context.writeAttr(key, "B_HSV32");
			break;
		case B_HSVA32:
			context.writeAttr(key, "B_HSVA32");
			break;
		case B_HLS24:
			context.writeAttr(key, "B_HLS24");
			break;
		case B_HLS32:
			context.writeAttr(key, "B_HLS32");
			break;
		case B_HLSA32:
			context.writeAttr(key, "B_HLSA32");
			break;
		case B_CMY24:
			context.writeAttr(key, "B_CMY24");
			break;
		case B_CMY32:
			context.writeAttr(key, "B_CMY32");
			break;
		case B_CMYA32:
			context.writeAttr(key, "B_CMYA32");
			break;
		case B_CMYK32:
			context.writeAttr(key, "B_CMYK32");
			break;
		default:
			break;
	}
}
示例#24
0
void ConnectionIO::xmlExportContent(
    ExportContext&						context) const {

    context.beginContent();

    // write output
    {
        context.beginElement(_OUTPUT_ELEMENT);
        context.beginContent();

        // describe the node
//		LiveNodeIO nodeIO(
//			m_manager,
//			dynamic_cast<NodeSetIOContext*>(&context),
//			m_outputNode);
        context.writeObject(m_outputNodeIO);

//		context.beginElement(_LIVE_NODE_ELEMENT);
//		if(m_outputNodeKey.Length()) {
//			context.writeAttr("key", m_outputNodeKey);
//		}
//		else {
//			_write_simple("name", m_outputNodeName.String(), context);
//			_write_node_kinds(m_outputNodeKind, context);
//		}
//		context.endElement(); // _LIVE_NODE_ELEMENT

        // describe the output

        _write_simple("name", m_outputName.String(), context);

        if(m_outputFormat.type > B_MEDIA_UNKNOWN_TYPE) {
            MediaFormatIO io(m_outputFormat);
            context.writeObject(&io);
        }

        context.endElement(); // _OUTPUT_ELEMENT
    }

    // write input
    {
        context.beginElement(_INPUT_ELEMENT);
        context.beginContent();

        // describe the node
//		LiveNodeIO nodeIO(
//			m_manager,
//			dynamic_cast<NodeSetIOContext*>(&context),
//			m_inputNode);
        context.writeObject(m_inputNodeIO);

//		context.beginElement(_LIVE_NODE_ELEMENT);
//		if(m_inputNodeKey.Length()) {
//			context.writeAttr("key", m_inputNodeKey);
//		}
//		else {
//			_write_simple("name", m_inputNodeName.String(), context);
//			_write_node_kinds(m_inputNodeKind, context);
//		}
//		context.endElement(); // _LIVE_NODE_ELEMENT

        // describe the input

        _write_simple("name", m_inputName.String(), context);

        if(m_inputFormat.type > B_MEDIA_UNKNOWN_TYPE) {
            MediaFormatIO io(m_inputFormat);
            context.writeObject(&io);
        }

        context.endElement(); // _INPUT_ELEMENT
    }

    // write requested format
    if(m_requestedFormat.type > B_MEDIA_UNKNOWN_TYPE) {
        MediaFormatIO io(m_requestedFormat);
        BString comment = "\n";
        comment << context.indentString();
        comment << "<!-- initial requested format -->";
        context.writeString(comment);
        context.writeObject(&io);
    }
}
示例#25
0
static void ExportMeshLod(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, FArchive& Ar, FArchive& Ar2)
{
	guard(ExportMeshLod);

	// Opening brace
	Ar.Printf("{\n");

	// Asset
	Ar.Printf(
		"  \"asset\" : {\n"
		"    \"generator\" : \"UE Viewer (umodel) build %s\",\n"
		"    \"version\" : \"2.0\"\n"
		"  },\n",
		STR(GIT_REVISION));

	// Scene
	Ar.Printf(
		"  \"scene\" : 0,\n"
		"  \"scenes\" : [\n"
		"    {\n"
		"      \"nodes\" : [ 0 ]\n"
		"    }\n"
		"  ],\n"
	);

	// Nodes
	if (!Context.IsSkeletal())
	{
		Ar.Printf(
			"  \"nodes\" : [\n"
			"    {\n"
			"      \"name\" : \"%s\",\n"
			"      \"mesh\" : 0\n"
			"    }\n"
			"  ],\n",
			Context.MeshName
		);
	}
	else
	{
		ExportSkinData(Context, static_cast<const CSkelMeshLod&>(Lod), Ar);
	}

	// Materials
	Ar.Printf("  \"materials\" : [\n");
	for (int i = 0; i < Lod.Sections.Num(); i++)
	{
		ExportMaterial(Lod.Sections[i].Material, Ar, i, i == Lod.Sections.Num() - 1);
	}
	Ar.Printf("  ],\n");

	// Meshes
	Ar.Printf(
		"  \"meshes\" : [\n"
		"    {\n"
		"      \"primitives\" : [\n"
	);
	for (int i = 0; i < Lod.Sections.Num(); i++)
	{
		ExportSection(Context, Lod, Verts, i, Ar);
	}
	Ar.Printf(
		"      ],\n"
		"      \"name\" : \"%s\"\n"
		"    }\n"
		"  ],\n",
		Context.MeshName
	);

	// Write animations
	if (Context.IsSkeletal() && Context.SkelMesh->Anim)
	{
		ExportAnimations(Context, Ar);
	}

	// Write buffers
	int bufferLength = 0;
	for (int i = 0; i < Context.Data.Num(); i++)
	{
		bufferLength += Context.Data[i].DataSize;
	}

	Ar.Printf(
		"  \"buffers\" : [\n"
		"    {\n"
		"      \"uri\" : \"%s.bin\",\n"
		"      \"byteLength\" : %d\n"
		"    }\n"
		"  ],\n",
		Context.MeshName, bufferLength
	);

	// Write bufferViews
	Ar.Printf(
		"  \"bufferViews\" : [\n"
	);
	int bufferOffset = 0;
	for (int i = 0; i < Context.Data.Num(); i++)
	{
		const BufferData& B = Context.Data[i];
		Ar.Printf(
			"    {\n"
			"      \"buffer\" : 0,\n"
			"      \"byteOffset\" : %d,\n"
			"      \"byteLength\" : %d\n"
			"    }%s\n",
			bufferOffset,
			B.DataSize,
			i == (Context.Data.Num()-1) ? "" : ","
		);
		bufferOffset += B.DataSize;
	}
	Ar.Printf(
		"  ],\n"
	);

	// Write accessors
	Ar.Printf(
		"  \"accessors\" : [\n"
	);
	for (int i = 0; i < Context.Data.Num(); i++)
	{
		const BufferData& B = Context.Data[i];
		Ar.Printf(
			"    {\n"
			"      \"bufferView\" : %d,\n",
			i
		);
		if (B.bNormalized)
		{
			Ar.Printf("      \"normalized\" : true,\n");
		}
		if (B.BoundsMin.Len())
		{
			Ar.Printf(
				"      \"min\" : %s,\n"
				"      \"max\" : %s,\n",
				*B.BoundsMin, *B.BoundsMax
			);
		}
		Ar.Printf(
			"      \"componentType\" : %d,\n"
			"      \"count\" : %d,\n"
			"      \"type\" : \"%s\"\n"
			"    }%s\n",
			B.ComponentType,
			B.Count,
			B.Type,
			i == (Context.Data.Num()-1) ? "" : ","
		);
	}
	Ar.Printf(
		"  ]\n"
	);

	// Write binary data
	guard(WriteBIN);
	for (int i = 0; i < Context.Data.Num(); i++)
	{
		const BufferData& B = Context.Data[i];
#if MAX_DEBUG
		assert(B.FillCount == B.Count);
#endif
		Ar2.Serialize(B.Data, B.DataSize);
	}
	unguard;

	// Closing brace
	Ar.Printf("}\n");

	unguard;
}
示例#26
0
void export_multistream_vid_info_attr(
	media_multistream_format::vid_info f,
	ExportContext& context) {
	
	// +++++ no wildcard to compare against (assume 0 == wildcard?)
	
	context.writeAttr(gKey_frame_rate, f.frame_rate);
	context.writeAttr(gKey_width, (uint32)f.width);
	context.writeAttr(gKey_height, (uint32)f.height);
	write_colorspace_attr(gKey_space, f.space, context);
	context.writeAttr(gKey_sampling_rate, f.sampling_rate);
	
	switch(f.sample_format) {
		case B_UNDEFINED_SAMPLES:
			context.writeAttr(gKey_sample_format, "B_UNDEFINED_SAMPLES");
			break;
		case B_LINEAR_SAMPLES:
			context.writeAttr(gKey_sample_format, "B_LINEAR_SAMPLES");
			break;
		case B_FLOAT_SAMPLES:
			context.writeAttr(gKey_sample_format, "B_FLOAT_SAMPLES");
			break;
		case B_MULAW_SAMPLES:
			context.writeAttr(gKey_sample_format, "B_MULAW_SAMPLES");
			break;
		default:
			break;
	}

	switch(f.byte_order) {
		case B_MEDIA_BIG_ENDIAN:
			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
			break;
		case B_MEDIA_LITTLE_ENDIAN:
			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
			break;
		default:
			break;
	}
	
	context.writeAttr(gKey_channel_count, (uint32)f.channel_count);
}
示例#27
0
void ConnectionIO::xmlExportEnd(
    ExportContext&						context) const {

    context.endElement(); // _CONNECTION_ELEMENT
}
示例#28
0
void write_media_type(
	media_type t,
	ExportContext& context) {

	context.beginElement(MediaFormatIO::s_media_type_tag);
	context.beginContent();
	
	switch(t) {
		case B_MEDIA_NO_TYPE:
			context.writeString("B_MEDIA_NO_TYPE");
			break;
		case B_MEDIA_UNKNOWN_TYPE:
			context.writeString("B_MEDIA_UNKNOWN_TYPE");
			break;
		case B_MEDIA_RAW_AUDIO:
			context.writeString("B_MEDIA_RAW_AUDIO");
			break;
		case B_MEDIA_RAW_VIDEO:
			context.writeString("B_MEDIA_RAW_VIDEO");
			break;
		case B_MEDIA_VBL:
			context.writeString("B_MEDIA_VBL");
			break;
		case B_MEDIA_TIMECODE:
			context.writeString("B_MEDIA_TIMECODE");
			break;
		case B_MEDIA_MIDI:
			context.writeString("B_MEDIA_MIDI");
			break;
		case B_MEDIA_TEXT:
			context.writeString("B_MEDIA_TEXT");
			break;
		case B_MEDIA_HTML:
			context.writeString("B_MEDIA_HTML");
			break;
		case B_MEDIA_MULTISTREAM:
			context.writeString("B_MEDIA_MULTISTREAM");
			break;
		case B_MEDIA_PARAMETERS:
			context.writeString("B_MEDIA_PARAMETERS");
			break;
		case B_MEDIA_ENCODED_AUDIO:
			context.writeString("B_MEDIA_ENCODED_AUDIO");
			break;
		case B_MEDIA_ENCODED_VIDEO:
			context.writeString("B_MEDIA_ENCODED_VIDEO");
			break;
		default: {
			BString val;
			val << (uint32)t;
			context.writeString(val);
		}
	}
	context.endElement();
}
示例#29
0
static void ExportSection(ExportContext& Context, const CBaseMeshLod& Lod, const CMeshVertex* Verts, int SectonIndex, FArchive& Ar)
{
	guard(ExportSection);

	int VertexSize = Context.IsSkeletal() ? sizeof(CSkelMeshVertex) : sizeof(CStaticMeshVertex);

	const CMeshSection& S = Lod.Sections[SectonIndex];
	bool bLast = (SectonIndex == Lod.Sections.Num()-1);

	// Remap section indices to local indices
	CIndexBuffer::IndexAccessor_t GetIndex = Lod.Indices.GetAccessor();
	TArray<int> indexRemap; // old vertex index -> new vertex index
	indexRemap.Init(-1, Lod.NumVerts);
	int numLocalVerts = 0;
	int numLocalIndices = S.NumFaces * 3;
	for (int idx = 0; idx < numLocalIndices; idx++)
	{
		int vertIndex = GetIndex(S.FirstIndex + idx);
		if (indexRemap[vertIndex] == -1)
		{
			indexRemap[vertIndex] = numLocalVerts++;
		}
	}

	// Prepare buffers
	int IndexBufIndex = Context.Data.AddZeroed();
	int PositionBufIndex = Context.Data.AddZeroed();
	int NormalBufIndex = Context.Data.AddZeroed();
	int TangentBufIndex = Context.Data.AddZeroed();

	int BonesBufIndex = -1;
	int WeightsBufIndex = -1;
	if (Context.IsSkeletal())
	{
		BonesBufIndex = Context.Data.AddZeroed();
		WeightsBufIndex = Context.Data.AddZeroed();
	}

	int UVBufIndex[MAX_MESH_UV_SETS];
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		UVBufIndex[i] = Context.Data.AddZeroed();
	}

	BufferData& IndexBuf = Context.Data[IndexBufIndex];
	BufferData& PositionBuf = Context.Data[PositionBufIndex];
	BufferData& NormalBuf = Context.Data[NormalBufIndex];
	BufferData& TangentBuf = Context.Data[TangentBufIndex];
	BufferData* UVBuf[MAX_MESH_UV_SETS];
	BufferData* BonesBuf = NULL;
	BufferData* WeightsBuf = NULL;

	PositionBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3));
	NormalBuf.Setup(numLocalVerts, "VEC3", BufferData::FLOAT, sizeof(CVec3));
	TangentBuf.Setup(numLocalVerts, "VEC4", BufferData::FLOAT, sizeof(CVec4));
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		UVBuf[i] = &Context.Data[UVBufIndex[i]];
		UVBuf[i]->Setup(numLocalVerts, "VEC2", BufferData::FLOAT, sizeof(CMeshUVFloat));
	}

	if (Context.IsSkeletal())
	{
		BonesBuf = &Context.Data[BonesBufIndex];
		WeightsBuf = &Context.Data[WeightsBufIndex];
		BonesBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_SHORT, sizeof(uint16)*4);
		WeightsBuf->Setup(numLocalVerts, "VEC4", BufferData::UNSIGNED_BYTE, sizeof(uint32), /*InNormalized=*/ true);
	}

	// Prepare and build indices
	TArray<int> localIndices;
	localIndices.AddUninitialized(numLocalIndices);
	int* pIndex = localIndices.GetData();
	for (int i = 0; i < numLocalIndices; i++)
	{
		*pIndex++ = GetIndex(S.FirstIndex + i);
	}

	if (numLocalVerts <= 65536)
	{
		IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_SHORT, sizeof(uint16));
		for (int idx = 0; idx < numLocalIndices; idx++)
		{
			IndexBuf.Put<uint16>(indexRemap[localIndices[idx]]);
		}
	}
	else
	{
		IndexBuf.Setup(numLocalIndices, "SCALAR", BufferData::UNSIGNED_INT, sizeof(uint32));
		for (int idx = 0; idx < numLocalIndices; idx++)
		{
			IndexBuf.Put<uint32>(indexRemap[localIndices[idx]]);
		}
	}

	// Build reverse index map for fast lookup of vertex by its new index.
	// It maps new vertex index to old vertex index.
	TArray<int> revIndexMap;
	revIndexMap.AddUninitialized(numLocalVerts);
	for (int i = 0; i < indexRemap.Num(); i++)
	{
		int newIndex = indexRemap[i];
		if (newIndex != -1)
		{
			revIndexMap[newIndex] = i;
		}
	}

	// Build vertices
	for (int i = 0; i < numLocalVerts; i++)
	{
		int vertIndex = revIndexMap[i];
		const CMeshVertex& V = VERT(vertIndex);

		CVec3 Position = V.Position;

		CVec4 Normal, Tangent;
		Unpack(Normal, V.Normal);
		Unpack(Tangent, V.Tangent);
		// Unreal (and we are) using normal.w for computing binormal. glTF
		// uses tangent.w for that. Make this value exactly 1.0 of -1.0 to make glTF
		// validator happy.
	#if 0
		// There's some problem: V.Normal.W == 0x80 -> -1.008 instead of -1.0
		if (Normal.w > 1.001 || Normal.w < -1.001)
		{
			appError("%X -> %g\n", V.Normal.Data, Normal.w);
		}
	#endif
		Tangent.w = (Normal.w < 0) ? -1 : 1;

		TransformPosition(Position);
		TransformDirection(Normal);
		TransformDirection(Tangent);

		Normal.Normalize();
		Tangent.Normalize();

		// Fill buffers
		PositionBuf.Put(Position);
		NormalBuf.Put(Normal.xyz);
		TangentBuf.Put(Tangent);
		UVBuf[0]->Put(V.UV);
	}

	// Compute bounds for PositionBuf
	CVec3 Mins, Maxs;
	ComputeBounds((CVec3*)PositionBuf.Data, numLocalVerts, sizeof(CVec3), Mins, Maxs);
	char buf[256];
	appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Mins));
	PositionBuf.BoundsMin = buf;
	appSprintf(ARRAY_ARG(buf), "[ %g, %g, %g ]", VECTOR_ARG(Maxs));
	PositionBuf.BoundsMax = buf;

	if (Context.IsSkeletal())
	{
		for (int i = 0; i < numLocalVerts; i++)
		{
			int vertIndex = revIndexMap[i];
			const CMeshVertex& V0 = VERT(vertIndex);
			const CSkelMeshVertex& V = static_cast<const CSkelMeshVertex&>(V0);

			int16 Bones[NUM_INFLUENCES];
			static_assert(NUM_INFLUENCES == 4, "Code designed for 4 influences");
			static_assert(sizeof(Bones) == sizeof(V.Bone), "Unexpected V.Bones size");
			memcpy(Bones, V.Bone, sizeof(Bones));
			for (int j = 0; j < NUM_INFLUENCES; j++)
			{
				// We have INDEX_NONE as list terminator, should replace with something else for glTF
				if (Bones[j] == INDEX_NONE)
				{
					Bones[j] = 0;
				}
			}

			BonesBuf->Put(*(uint64*)&Bones);
			WeightsBuf->Put(V.PackedWeights);
		}
	}

	// Secondary UVs
	for (int uvIndex = 1; uvIndex < Lod.NumTexCoords; uvIndex++)
	{
		BufferData* pBuf = UVBuf[uvIndex];
		const CMeshUVFloat* srcUV = Lod.ExtraUV[uvIndex-1];
		for (int i = 0; i < numLocalVerts; i++)
		{
			int vertIndex = revIndexMap[i];
			pBuf->Put(srcUV[vertIndex]);
		}
	}

	// Write primitive information to json
	Ar.Printf(
		"        {\n"
		"          \"attributes\" : {\n"
		"            \"POSITION\" : %d,\n"
		"            \"NORMAL\" : %d,\n"
		"            \"TANGENT\" : %d,\n",
		PositionBufIndex, NormalBufIndex, TangentBufIndex
	);
	if (Context.IsSkeletal())
	{
		Ar.Printf(
			"            \"JOINTS_0\" : %d,\n"
			"            \"WEIGHTS_0\" : %d,\n",
			BonesBufIndex, WeightsBufIndex
		);
	}
	for (int i = 0; i < Lod.NumTexCoords; i++)
	{
		Ar.Printf(
			"            \"TEXCOORD_%d\" : %d%s\n",
			i, UVBufIndex[i], i < (Lod.NumTexCoords-1) ? "," : ""
		);
	}

	Ar.Printf(
		"          },\n"
		"          \"indices\" : %d,\n"
		"          \"material\" : %d\n"
		"        }%s\n",
		IndexBufIndex, SectonIndex,
		SectonIndex < (Lod.Sections.Num()-1) ? "," : ""
	);

	unguard;
}
示例#30
0
static void ExportAnimations(ExportContext& Context, FArchive& Ar)
{
	guard(ExportAnimations);

	const CAnimSet* Anim = Context.SkelMesh->Anim;
	int NumBones = Context.SkelMesh->RefSkeleton.Num();

	// Build mesh to anim bone map

	TArray<int> BoneMap;
	BoneMap.Init(-1, NumBones);
	TArray<int> AnimBones;
	AnimBones.Empty(NumBones);

	for (int i = 0; i < NumBones; i++)
	{
		const CSkelMeshBone &B = Context.SkelMesh->RefSkeleton[i];
		for (int j = 0; j < Anim->TrackBoneNames.Num(); j++)
		{
			if (!stricmp(B.Name, Anim->TrackBoneNames[j]))
			{
				BoneMap[i] = j;			// lookup CAnimSet bone by mesh bone index
				AnimBones.Add(i);		// indicate that the bone has animation
				break;
			}
		}
	}

	Ar.Printf(
		"  \"animations\" : [\n"
	);

	int FirstDataIndex = Context.Data.Num();

	// Iterate over all animations
	for (int SeqIndex = 0; SeqIndex < Anim->Sequences.Num(); SeqIndex++)
	{
		const CAnimSequence &Seq = *Anim->Sequences[SeqIndex];

		Ar.Printf(
			"    {\n"
			"      \"name\" : \"%s\",\n",
			*Seq.Name
		);

		struct AnimSampler
		{
			enum ChannelType
			{
				TRANSLATION,
				ROTATION
			};

			int BoneNodeIndex;
			ChannelType Type;
			const CAnimTrack* Track;
		};

		TArray<AnimSampler> Samplers;
		Samplers.Empty(AnimBones.Num() * 2);

		//!! Optimization:
		//!! 1. there will be missing tracks (AnimRotationOnly etc) - drop such samplers
		//!! 2. store all time tracks in a single BufferView, all rotation tracks in another, and all position track in 3rd one - this
		//!!    will reduce amount of BufferViews in json text (combine them by data type)

		// Prepare channels array
		Ar.Printf("      \"channels\" : [\n");
		for (int BoneIndex = 0; BoneIndex < AnimBones.Num(); BoneIndex++)
		{
			int MeshBoneIndex = AnimBones[BoneIndex];
			int AnimBoneIndex = BoneMap[MeshBoneIndex];

			const CAnimTrack* Track = Seq.Tracks[AnimBoneIndex];

			int TranslationSamplerIndex = Samplers.Num();
			AnimSampler* Sampler = new (Samplers) AnimSampler;
			Sampler->Type = AnimSampler::TRANSLATION;
			Sampler->BoneNodeIndex = MeshBoneIndex + FIRST_BONE_NODE;
			Sampler->Track = Track;

			int RotationSamplerIndex = Samplers.Num();
			Sampler = new (Samplers) AnimSampler;
			Sampler->Type = AnimSampler::ROTATION;
			Sampler->BoneNodeIndex = MeshBoneIndex + FIRST_BONE_NODE;
			Sampler->Track = Track;

			// Print glTF information. Not using usual formatting here to make output a little bit more compact.
			Ar.Printf(
				"        { \"sampler\" : %d, \"target\" : { \"node\" : %d, \"path\" : \"%s\" } },\n",
				TranslationSamplerIndex, MeshBoneIndex + FIRST_BONE_NODE, "translation"
			);
			Ar.Printf(
				"        { \"sampler\" : %d, \"target\" : { \"node\" : %d, \"path\" : \"%s\" } }%s\n",
				RotationSamplerIndex, MeshBoneIndex + FIRST_BONE_NODE, "rotation", BoneIndex == AnimBones.Num()-1 ? "" : ","
			);
		}
		Ar.Printf("      ],\n");

		// Prepare samplers
		Ar.Printf("      \"samplers\" : [\n");
		for (int SamplerIndex = 0; SamplerIndex < Samplers.Num(); SamplerIndex++)
		{
			const AnimSampler& Sampler = Samplers[SamplerIndex];

			// Prepare time array
			const TArray<float>* TimeArray = (Sampler.Type == AnimSampler::TRANSLATION) ? &Sampler.Track->KeyPosTime : &Sampler.Track->KeyQuatTime;
			if (TimeArray->Num() == 0)
			{
				// For this situation, use track's time array
				TimeArray = &Sampler.Track->KeyTime;
			}
			int NumKeys = Sampler.Type == (AnimSampler::TRANSLATION) ? Sampler.Track->KeyPos.Num() : Sampler.Track->KeyQuat.Num();

			int TimeBufIndex = Context.Data.AddZeroed();
			BufferData& TimeBuf = Context.Data[TimeBufIndex];
			TimeBuf.Setup(NumKeys, "SCALAR", BufferData::FLOAT, sizeof(float));

			float RateScale = 1.0f / Seq.Rate;
			float LastFrameTime = 0;
			if (TimeArray->Num() == 0 || NumKeys == 1)
			{
				// Fill with equally spaced values
				for (int i = 0; i < NumKeys; i++)
				{
					TimeBuf.Put(i * RateScale);
				}
				LastFrameTime = NumKeys-1;
			}
			else
			{
				for (int i = 0; i < TimeArray->Num(); i++)
				{
					TimeBuf.Put((*TimeArray)[i] * RateScale);
				}
				LastFrameTime = (*TimeArray)[TimeArray->Num()-1];
			}
			// Prepare min/max values for time track, it's required by glTF standard
			TimeBuf.BoundsMin = "[ 0 ]";
			char buf[64];
			appSprintf(ARRAY_ARG(buf), "[ %g ]", LastFrameTime * RateScale);
			TimeBuf.BoundsMax = buf;

			// Try to reuse TimeBuf from previous tracks
			TimeBufIndex = Context.GetFinalIndexForLastBlock(FirstDataIndex);

			// Prepare data
			int DataBufIndex = Context.Data.AddZeroed();
			BufferData& DataBuf = Context.Data[DataBufIndex];
			if (Sampler.Type == AnimSampler::TRANSLATION)
			{
				// Translation track
				DataBuf.Setup(NumKeys, "VEC3", BufferData::FLOAT, sizeof(CVec3));
				for (int i = 0; i < NumKeys; i++)
				{
					CVec3 Pos = Sampler.Track->KeyPos[i];
					TransformPosition(Pos);
					DataBuf.Put(Pos);
				}
			}
			else
			{
				// Rotation track
				DataBuf.Setup(NumKeys, "VEC4", BufferData::FLOAT, sizeof(CQuat));
				for (int i = 0; i < NumKeys; i++)
				{
					CQuat Rot = Sampler.Track->KeyQuat[i];
					TransformRotation(Rot);
					if (Sampler.BoneNodeIndex - FIRST_BONE_NODE == 0)
					{
						Rot.Conjugate();
					}
					DataBuf.Put(Rot);
				}
			}

			// Try to reuse data block as well
			DataBufIndex = Context.GetFinalIndexForLastBlock(FirstDataIndex);

			// Write glTF info
			Ar.Printf(
				"        { \"input\" : %d, \"output\" : %d }%s\n",
				TimeBufIndex, DataBufIndex, SamplerIndex == Samplers.Num()-1 ? "" : ","
			);
		}
		Ar.Printf("      ]\n");

		Ar.Printf("    }%s\n", SeqIndex == Anim->Sequences.Num()-1 ? "" : ",");
	}

	Ar.Printf("  ],\n");

	unguard;
}