Esempio n. 1
0
// ------------------------------------------------------------------------------------------------
// read an array of floats
void ParseVectorDataArray(std::vector<float>& out, const Element& el)
{
    out.resize( 0 );
    const TokenList& tok = el.Tokens();
    if(tok.empty()) {
        ParseError("unexpected empty element",&el);
    }

    if(tok[0]->IsBinary()) {
        const char* data = tok[0]->begin(), *end = tok[0]->end();

        char type;
        uint32_t count;
        ReadBinaryDataArrayHead(data, end, type, count, el);

        if(!count) {
            return;
        }

        if (type != 'd' && type != 'f') {
            ParseError("expected float or double array (binary)",&el);
        }

        std::vector<char> buff;
        ReadBinaryDataArray(type, count, data, end, buff, el);

        ai_assert(data == end);
        ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));

        if (type == 'd') {
            const double* d = reinterpret_cast<const double*>(&buff[0]);
            for (unsigned int i = 0; i < count; ++i, ++d) {
                out.push_back(static_cast<float>(*d));
            }
        }
        else if (type == 'f') {
            const float* f = reinterpret_cast<const float*>(&buff[0]);
            for (unsigned int i = 0; i < count; ++i, ++f) {
                out.push_back(*f);
            }
        }

        return;
    }

    const size_t dim = ParseTokenAsDim(*tok[0]);

    // see notes in ParseVectorDataArray()
    out.reserve(dim);

    const Scope& scope = GetRequiredScope(el);
    const Element& a = GetRequiredElement(scope,"a",&el);

    for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
        const float ival = ParseTokenAsFloat(**it++);
        out.push_back(ival);
    }
}
Esempio n. 2
0
// ------------------------------------------------------------------------------------------------
// read an array of int64_ts
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
{
    out.resize( 0 );
    const TokenList& tok = el.Tokens();
    if (tok.empty()) {
        ParseError("unexpected empty element", &el);
    }

    if (tok[0]->IsBinary()) {
        const char* data = tok[0]->begin(), *end = tok[0]->end();

        char type;
        uint32_t count;
        ReadBinaryDataArrayHead(data, end, type, count, el);

        if (!count) {
            return;
        }

        if (type != 'l') {
            ParseError("expected long array (binary)", &el);
        }

        std::vector<char> buff;
        ReadBinaryDataArray(type, count, data, end, buff, el);

        ai_assert(data == end);
        ai_assert(buff.size() == count * 8);

        out.reserve(count);

        const int64_t* ip = reinterpret_cast<const int64_t*>(&buff[0]);
        for (unsigned int i = 0; i < count; ++i, ++ip) {
            BE_NCONST int64_t val = *ip;
            AI_SWAP8(val);
            out.push_back(val);
        }

        return;
    }

    const size_t dim = ParseTokenAsDim(*tok[0]);

    // see notes in ParseVectorDataArray()
    out.reserve(dim);

    const Scope& scope = GetRequiredScope(el);
    const Element& a = GetRequiredElement(scope, "a", &el);

    for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end;) {
        const int64_t ival = ParseTokenAsInt64(**it++);

        out.push_back(ival);
    }
}
Esempio n. 3
0
// ------------------------------------------------------------------------------------------------
// read an array of float2 tuples
void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
{
    out.resize( 0 );
    const TokenList& tok = el.Tokens();
    if(tok.empty()) {
        ParseError("unexpected empty element",&el);
    }

    if(tok[0]->IsBinary()) {
        const char* data = tok[0]->begin(), *end = tok[0]->end();

        char type;
        uint32_t count;
        ReadBinaryDataArrayHead(data, end, type, count, el);

        if(count % 2 != 0) {
            ParseError("number of floats is not a multiple of two (2) (binary)",&el);
        }

        if(!count) {
            return;
        }

        if (type != 'd' && type != 'f') {
            ParseError("expected float or double array (binary)",&el);
        }

        std::vector<char> buff;
        ReadBinaryDataArray(type, count, data, end, buff, el);

        ai_assert(data == end);
        ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));

        const uint32_t count2 = count / 2;
        out.reserve(count2);

        if (type == 'd') {
            const double* d = reinterpret_cast<const double*>(&buff[0]);
            for (unsigned int i = 0; i < count2; ++i, d += 2) {
                out.push_back(aiVector2D(static_cast<float>(d[0]),
                    static_cast<float>(d[1])));
            }
        }
        else if (type == 'f') {
            const float* f = reinterpret_cast<const float*>(&buff[0]);
            for (unsigned int i = 0; i < count2; ++i, f += 2) {
                out.push_back(aiVector2D(f[0],f[1]));
            }
        }

        return;
    }

    const size_t dim = ParseTokenAsDim(*tok[0]);

    // see notes in ParseVectorDataArray() above
    out.reserve(dim);

    const Scope& scope = GetRequiredScope(el);
    const Element& a = GetRequiredElement(scope,"a",&el);

    if (a.Tokens().size() % 2 != 0) {
        ParseError("number of floats is not a multiple of two (2)",&el);
    }
    for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
        aiVector2D v;
        v.x = ParseTokenAsFloat(**it++);
        v.y = ParseTokenAsFloat(**it++);

        out.push_back(v);
    }
}
Esempio n. 4
0
// ------------------------------------------------------------------------------------------------
// read an array of float3 tuples
void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
{
    out.resize( 0 );

    const TokenList& tok = el.Tokens();
    if(tok.empty()) {
        ParseError("unexpected empty element",&el);
    }

    if(tok[0]->IsBinary()) {
        const char* data = tok[0]->begin(), *end = tok[0]->end();

        char type;
        uint32_t count;
        ReadBinaryDataArrayHead(data, end, type, count, el);

        if(count % 3 != 0) {
            ParseError("number of floats is not a multiple of three (3) (binary)",&el);
        }

        if(!count) {
            return;
        }

        if (type != 'd' && type != 'f') {
            ParseError("expected float or double array (binary)",&el);
        }

        std::vector<char> buff;
        ReadBinaryDataArray(type, count, data, end, buff, el);

        ai_assert(data == end);
        ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));

        const uint32_t count3 = count / 3;
        out.reserve(count3);

        if (type == 'd') {
            const double* d = reinterpret_cast<const double*>(&buff[0]);
            for (unsigned int i = 0; i < count3; ++i, d += 3) {
                out.push_back(aiVector3D(static_cast<float>(d[0]),
                    static_cast<float>(d[1]),
                    static_cast<float>(d[2])));
            }
            // for debugging
            /*for ( size_t i = 0; i < out.size(); i++ ) {
                aiVector3D vec3( out[ i ] );
                std::stringstream stream;
                stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl;
                DefaultLogger::get()->info( stream.str() );
            }*/
        }
        else if (type == 'f') {
            const float* f = reinterpret_cast<const float*>(&buff[0]);
            for (unsigned int i = 0; i < count3; ++i, f += 3) {
                out.push_back(aiVector3D(f[0],f[1],f[2]));
            }
        }

        return;
    }

    const size_t dim = ParseTokenAsDim(*tok[0]);

    // may throw bad_alloc if the input is rubbish, but this need
    // not to be prevented - importing would fail but we wouldn't
    // crash since assimp handles this case properly.
    out.reserve(dim);

    const Scope& scope = GetRequiredScope(el);
    const Element& a = GetRequiredElement(scope,"a",&el);

    if (a.Tokens().size() % 3 != 0) {
        ParseError("number of floats is not a multiple of three (3)",&el);
    }
    for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
        aiVector3D v;
        v.x = ParseTokenAsFloat(**it++);
        v.y = ParseTokenAsFloat(**it++);
        v.z = ParseTokenAsFloat(**it++);

        out.push_back(v);
    }
}
void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source, 
	const std::string& MappingInformationType,
	const std::string& ReferenceInformationType,
	const char* dataElementName,
	const char* indexDataElementName,
	size_t vertex_count,
	const std::vector<unsigned int>& mapping_counts,
	const std::vector<unsigned int>& mapping_offsets,
	const std::vector<unsigned int>& mappings)
{
	std::vector<T> tempUV;
	ParseVectorDataArray(tempUV,GetRequiredElement(source,dataElementName));

	// handle permutations of Mapping and Reference type - it would be nice to
	// deal with this more elegantly and with less redundancy, but right
	// now it seems unavoidable.
	if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") {	
		data_out.resize(vertex_count);
		for (size_t i = 0, e = tempUV.size(); i < e; ++i) {

			const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
			for (unsigned int j = istart; j < iend; ++j) {
				data_out[mappings[j]] = tempUV[i];
			}
		}
	}
	else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") {	
		data_out.resize(vertex_count);

		std::vector<int> uvIndices;
		ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));

		for (size_t i = 0, e = uvIndices.size(); i < e; ++i) {

			const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
			for (unsigned int j = istart; j < iend; ++j) {
				if(static_cast<size_t>(uvIndices[i]) >= tempUV.size()) {
					DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
				}
				data_out[mappings[j]] = tempUV[uvIndices[i]];
			}
		}
	}
	else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {	
		if (tempUV.size() != vertex_count) {
			FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") 
				<< tempUV.size() << ", expected " << vertex_count
			);
			return;
		}

		data_out.swap(tempUV);
	}
	else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") {	
		data_out.resize(vertex_count);

		std::vector<int> uvIndices;
		ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));

		if (uvIndices.size() != vertex_count) {
			FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping");
			return;
		}

		unsigned int next = 0;
		BOOST_FOREACH(int i, uvIndices) {
			if(static_cast<size_t>(i) >= tempUV.size()) {
				DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
			}

			data_out[next++] = tempUV[i];
		}
	}