コード例 #1
0
ファイル: joint.c プロジェクト: umibps/KABURAGI
void PmxJointRead(PMX_JOINT* joint, uint8* data, PMX_DATA_INFO* info, size_t* data_size)
{
	PMX_JOINT_UNIT unit;
	MEMORY_STREAM stream = {data, 0, (size_t)(info->end - data), 1};
	char *name_ptr;
	int length;
	TEXT_ENCODE *encode = info->encoding;
	uint8 type;

	// 日本語名
	length = GetTextFromStream((char*)data, &name_ptr);
	joint->name = EncodeText(encode, name_ptr, length);
	stream.data_point = sizeof(int32) + length;

	// 英語名
	length = GetTextFromStream((char*)&data[stream.data_point], &name_ptr);
	joint->english_name = EncodeText(encode, name_ptr, length);
	stream.data_point += sizeof(int32) + length;

	type = data[stream.data_point];
	stream.data_point++;
	joint->type = (eJOINT_TYPE)type;

	joint->rigid_body1_index = GetSignedValue(&data[stream.data_point], (int)info->rigid_body_index_size);
	stream.data_point += info->rigid_body_index_size;
	joint->rigid_body2_index = GetSignedValue(&data[stream.data_point], (int)info->rigid_body_index_size);
	stream.data_point += info->rigid_body_index_size;

	(void)MemRead(unit.position, sizeof(unit.position), 1, &stream);
	(void)MemRead(unit.rotation, sizeof(unit.rotation), 1, &stream);
	(void)MemRead(unit.position_lower_limit, sizeof(unit.position_lower_limit), 1, &stream);
	(void)MemRead(unit.position_upper_limit, sizeof(unit.position_upper_limit), 1, &stream);
	(void)MemRead(unit.rotation_lower_limit, sizeof(unit.rotation_lower_limit), 1, &stream);
	(void)MemRead(unit.rotation_upper_limit, sizeof(unit.rotation_upper_limit), 1, &stream);
	(void)MemRead(unit.position_stiffness, sizeof(unit.position_stiffness), 1, &stream);
	(void)MemRead(unit.rotation_stiffness, sizeof(unit.rotation_stiffness), 1, &stream);

	COPY_VECTOR3(joint->position, unit.position);
	COPY_VECTOR3(joint->rotation, unit.rotation);
	COPY_VECTOR3(joint->position_lower_limit, unit.position_lower_limit);
	COPY_VECTOR3(joint->position_upper_limit, unit.position_upper_limit);
	COPY_VECTOR3(joint->rotation_lower_limit, unit.rotation_lower_limit);
	COPY_VECTOR3(joint->rotation_upper_limit, unit.rotation_upper_limit);
	COPY_VECTOR3(joint->position_stiffness, unit.position_stiffness);
	COPY_VECTOR3(joint->rotation_stiffness, unit.rotation_stiffness);

	*data_size = stream.data_point;
}
コード例 #2
0
ファイル: bone.c プロジェクト: umibps/KABURAGI
void ReadPmd2Bone(
	PMD2_BONE* bone,
	MEMORY_STREAM_PTR stream,
	PMD_DATA_INFO* info,
	size_t* data_size
)
{
	BONE_UNIT unit;

	(void)MemRead(unit.name, 1, sizeof(unit.name), stream);
	(void)MemRead(&unit.parent_bone_id, sizeof(unit.parent_bone_id), 1, stream);
	(void)MemRead(&unit.child_bone_id, sizeof(unit.child_bone_id), 1, stream);
	(void)MemRead(&unit.type, sizeof(unit.type), 1, stream);
	(void)MemRead(&unit.target_bone_id, sizeof(unit.target_bone_id), 1, stream);
	(void)MemRead(&unit.position, sizeof(unit.position), 1, stream);
	bone->interface_data.name = EncodeText(&bone->application->encode,
		(char*)unit.name, sizeof(unit.name));
	bone->child_bone_index = unit.child_bone_id;
	bone->parent_bone_index = unit.parent_bone_id;
	bone->target_bone_index = unit.target_bone_id;
	bone->type = (ePMD2_BONE_TYPE)unit.type;
	SET_POSITION(bone->origin, unit.position);
	COPY_VECTOR3(bone->offset, bone->origin);
	*data_size = PMD_BONE_UNIT_SIZE;
}
コード例 #3
0
ファイル: bone.c プロジェクト: umibps/KABURAGI
void Pmd2BoneReadEnglishName(PMD2_BONE* bone, MEMORY_STREAM_PTR stream, int index)
{
	if(index >= 0)
	{
		char name[BONE_NAME_SIZE+1];
		(void)MemSeek(stream, BONE_NAME_SIZE*index, SEEK_SET);
		(void)MemRead(name, BONE_NAME_SIZE, 1, stream);
		bone->interface_data.english_name = EncodeText(
			&bone->application->encode, name, BONE_NAME_SIZE);
	}
}
コード例 #4
0
ファイル: CHTMLForm.cpp プロジェクト: Sdw195/Transcendence
ALERROR CHTMLForm::EncodeToBuffer (IWriteStream *pOutput) const

//	EncodeToBuffer
//
//	Encodes the form to the buffer

	{
	ALERROR error;
	int i;

	for (i = 0; i < m_Fields.GetCount(); i++)
		{
		//	Output field separator

		if (i != 0)
			if (error = pOutput->Write("&", 1))
				return error;

		//	Output key

		if (error = EncodeText(pOutput, m_Fields[i].sKey))
			return error;

		//	Output key/value separator

		if (error = pOutput->Write("=", 1))
			return error;

		//	Output value

		if (error = EncodeText(pOutput, m_Fields[i].sValue))
			return error;
		}

	return NOERROR;
	}
コード例 #5
0
const std::wstring FacadeDocumentProviderImpl::EncodeWorkshareId(const std::wstring& artifactId, const std::wstring& versionLabel, const std::wstring& repositoryId)
{
	return this->GetServiceId() + L"://" + EncodeText(artifactId) + L";" + EncodeText(versionLabel) + L";" + EncodeText(repositoryId);
}
コード例 #6
0
ファイル: material.c プロジェクト: umibps/KABURAGI
void PmxMaterialRead(
	PMX_MATERIAL* material,
	uint8* data,
	PMX_DATA_INFO* info,
	size_t* data_size
)
{
	MEMORY_STREAM stream = {data, 0, (size_t)(info->end - data), 1};
	PMX_METERIAL_UNIT unit;
	char *name_ptr;
	int texture_index_size = (int)info->texture_index_size;
	TEXT_ENCODE *encode = info->encoding;
	int length;
	int32 num_name_size;
	uint8 type;

	// 日本語名
	length = GetTextFromStream((char*)data, &name_ptr);
	material->interface_data.name = EncodeText(encode, name_ptr, length);
	stream.data_point += sizeof(int32) + length;

	// 英語名
	length = GetTextFromStream((char*)&data[stream.data_point], &name_ptr);
	material->interface_data.english_name = EncodeText(encode, name_ptr, length);
	stream.data_point += sizeof(int32) + length;

	(void)MemRead(unit.diffuse, sizeof(unit.diffuse), 1, &stream);
	(void)MemRead(unit.specular, sizeof(unit.specular), 1, &stream);
	(void)MemRead(&unit.shininess, sizeof(unit.shininess), 1, &stream);
	(void)MemRead(unit.ambient, sizeof(unit.ambient), 1, &stream);
	(void)MemRead(&unit.flags, sizeof(unit.flags), 1, &stream);
	(void)MemRead(unit.edge_color, sizeof(unit.edge_color), 1, &stream);
	(void)MemRead(&unit.edge_size, sizeof(unit.edge_size), 1, &stream);

	COPY_VECTOR3(material->ambient.base, unit.ambient);
	MaterialRGB3Calculate(&material->ambient);
	COPY_VECTOR4(material->diffuse.base, unit.diffuse);
	MaterialRGBA3Calculate(&material->diffuse);
	COPY_VECTOR3(material->specular.base, unit.specular);
	MaterialRGB3Calculate(&material->specular);
	COPY_VECTOR4(material->edge_color.base, unit.edge_color);
	MaterialRGBA3Calculate(&material->edge_color);
	material->shininess[0] = unit.shininess;
	material->edge_size[0] = unit.edge_size;
	material->interface_data.flags = unit.flags;

	material->main_texture_index = GetSignedValue(&data[stream.data_point], texture_index_size);
	stream.data_point += texture_index_size;
	material->sphere_texture_index = GetSignedValue(&data[stream.data_point], texture_index_size);
	stream.data_point += texture_index_size;

	type = data[stream.data_point];
	stream.data_point++;
	material->interface_data.sphere_texture_render_mode = (eMATERIAL_SPHERE_TEXTURE_RENDER_MODE)type;
	type = data[stream.data_point];
	stream.data_point++;
	if(type == 1)
	{
		material->interface_data.flags |= MATERIAL_FLAG_USE_SHARED_TOON_TEXTURE;
		type = data[stream.data_point];
		stream.data_point++;
		material->toon_texture_index = AdjustSharedToonTextureIndex(type);
	}
	else
	{
		material->interface_data.flags &= ~(MATERIAL_FLAG_USE_SHARED_TOON_TEXTURE);
		material->toon_texture_index = GetSignedValue(&data[stream.data_point], texture_index_size);
		stream.data_point += texture_index_size;
	}

	length = GetTextFromStream((char*)&data[stream.data_point], &name_ptr);
	stream.data_point += sizeof(int32) + length;

	(void)MemRead(&num_name_size, sizeof(num_name_size), 1, &stream);
	material->interface_data.index_range.count = num_name_size;

	*data_size = stream.data_point;
}
コード例 #7
0
ファイル: material.c プロジェクト: umibps/KABURAGI
void ReadPmd2Material(PMD2_MATERIAL* material, MEMORY_STREAM_PTR stream, size_t* data_size)
{
	PMD2_MATERIAL_UNIT unit;
	const char *separator = "*";
	const char *sph = ".sph";
	const char *spa = ".spa";
	char *texture;
	size_t name_length;
	(void)MemRead(unit.diffuse, sizeof(unit.diffuse), 1, stream);
	(void)MemRead(&unit.opacity, sizeof(unit.opacity), 1, stream);
	(void)MemRead(&unit.shininess, sizeof(unit.shininess), 1, stream);
	(void)MemRead(unit.specular, sizeof(unit.specular), 1, stream);
	(void)MemRead(unit.ambient, sizeof(unit.ambient), 1, stream);
	(void)MemRead(&unit.toon_texture_index, sizeof(unit.toon_texture_index), 1, stream);
	(void)MemRead(&unit.edge, sizeof(unit.edge), 1, stream);
	(void)MemRead(&unit.num_indices, sizeof(unit.num_indices), 1, stream);
	(void)MemRead(unit.texture_name, sizeof(unit.texture_name), 1, stream);
	texture = EncodeText(&material->application->encode, (char*)unit.texture_name, sizeof(unit.texture_name));
	name_length = strlen(texture);
	if(strstr(texture, separator) != NULL)
	{
		size_t length;
		char *main_texture;
		int num_tokens;
		char **tokens = SplitString(texture, separator, &num_tokens);
		main_texture = tokens[0];
		length = strlen(main_texture);
		if(length >= 4 && StringCompareIgnoreCase(&main_texture[length-4], sph) == 0)
		{
			material->interface_data.sphere_texture = MEM_STRDUP_FUNC(main_texture);
			material->interface_data.sphere_texture_render_mode = MATERIAL_MULTI_TEXTURE;
		}
		else
		{
			material->interface_data.main_texture = MEM_STRDUP_FUNC(main_texture);
		}
		Pmd2ModelAddTexture(material->model, main_texture);
		if(num_tokens == 2)
		{
			char *sub_texture = tokens[1];
			length = strlen(sub_texture);
			if(StringCompareIgnoreCase(&sub_texture[length-4], sph) == 0)
			{
				material->interface_data.sphere_texture = MEM_STRDUP_FUNC(sub_texture);
				material->interface_data.sphere_texture_render_mode = MATERIAL_MULTI_TEXTURE;
			}
			else if(StringCompareIgnoreCase(&sub_texture[length-4], spa) == 0)
			{
				material->interface_data.sphere_texture = MEM_STRDUP_FUNC(sub_texture);
				material->interface_data.sphere_texture_render_mode = MATERIAL_ADD_TEXTURE;
			}
		}
		MEM_FREE_FUNC(tokens);
	}
	else if(StringCompareIgnoreCase(&texture[name_length-4], sph) == 0)
	{
		material->interface_data.sphere_texture = MEM_STRDUP_FUNC(texture);
		material->interface_data.sphere_texture_render_mode = MATERIAL_MULTI_TEXTURE;
	}
	else
	{
		material->interface_data.main_texture = MEM_STRDUP_FUNC(texture);
	}
	COPY_VECTOR3(material->ambient, unit.ambient);
	material->ambient[3] = 1;
	COPY_VECTOR3(material->diffuse, unit.diffuse);
	material->diffuse[3] = 1;
	COPY_VECTOR3(material->specular, unit.specular);
	material->specular[3] = 1;
	material->interface_data.index_range.count = unit.num_indices;
	material->enable_edge = unit.edge != 0;
	material->toon_texture_index = AdjustSharedToonTextureIndex(unit.toon_texture_index);
	*data_size = PMD2_MATERIAL_UNIT_SIZE;
}
コード例 #8
0
ファイル: MimeDecode.cpp プロジェクト: mark711/mahogany
wxCharBuffer MIME::EncodeHeader(const String& in, wxFontEncoding enc)
{
   if ( !NeedsEncoding(in) )
      return in.ToAscii();

   // decide about the encoding to use if none specified
   if ( enc == wxFONTENCODING_SYSTEM )
   {
      // try to use the user current encoding first
      enc = wxLocale::GetSystemEncoding();
   }

   if ( wxCSConv(enc).FromWChar(NULL, 0, in.wc_str(wxConvLibc)) == wxCONV_FAILED )
   {
      // but if we can't encode with it, fall back to UTF-8 as it never fails
      enc = wxFONTENCODING_UTF8;
   }

   // get the encoding in RFC 2047 sense
   MIME::Encoding enc2047 = MIME::GetEncodingForFontEncoding(enc);

   if ( enc2047 == MIME::Encoding_Unknown )
   {
      FAIL_MSG( _T("should have valid MIME encoding") );

      enc2047 = MIME::Encoding_QuotedPrintable;
   }

   // get the name of the charset to use
   String csName = MIME::GetCharsetForFontEncoding(enc);
   if ( csName.empty() )
   {
      FAIL_MSG( _T("should have a valid charset name!") );

      csName = _T("UNKNOWN");
   }


   String headerEnc;
   headerEnc.reserve(2*in.length());

   // for QP we encode each header word separately as some might not need being
   // encoded at all and the header remains more readable if we don't encode
   // them unnecessarily, but for Base64 it's useless to do this as it's
   // unreadable anyhow so we just encode everything at once
   if ( enc2047 == MIME::Encoding_QuotedPrintable )
   {
      // encode each word of the header if necessary, taking into account one
      // added complication: white space between 2 consecutive encoded words is
      // ignored during decoding, so we must encode 2 consecutive words both of
      // which need encoding as one single encoded word or the space between
      // them would be lost
      bool lastWordEncoded = false;
      const wxArrayString words(wxStringTokenize(in));
      const size_t count = words.size();
      for ( size_t n = 0; n < count; ++n )
      {
         const wxString& word = words[n];
         if ( NeedsEncoding(word) )
         {
            const String wordEnc = EncodeText(word, enc, enc2047, csName);

            if ( lastWordEncoded )
            {
               // we need to merge the 2 consecutive encoded words together: we
               // do it by removing "?=" suffix from the previous word, adding
               // a space and remove the "=?charset?Q?" prefix from this word
               ASSERT_MSG( headerEnc.length() > 7, "bad QP-encoded last word" );
               headerEnc.RemoveLast(2); // "?="

               headerEnc += '_'; // space can be represented like this in QP

               const size_t posText = wordEnc.find("?Q?");
               ASSERT_MSG( posText != String::npos, "bad QP-encoded word" );
               headerEnc += wordEnc.substr(posText + 3);
            }
            else // last word not encoded, just append this one
            {
               if ( !headerEnc.empty() )
                  headerEnc += ' ';

               headerEnc += wordEnc;
            }

            lastWordEncoded = true;
         }
         else // this word doesn't need to be encoded, simply append it
         {
            if ( !headerEnc.empty() )
               headerEnc += ' ';

            headerEnc += word;

            lastWordEncoded = false;
         }
      }
   }
   else // MIME::Encoding_Base64
   {
      headerEnc = EncodeText(in, enc, enc2047, csName);
   }

   return headerEnc.ToAscii();
}
コード例 #9
0
ファイル: encoder.cpp プロジェクト: cubemoon/game-editor
bool KrEncoder::ProcessDoc( const TiXmlDocument& doc, KrEngine* engine, KrConsole* console )
{
	TiXmlElement* root = 0;
	TiXmlElement* rootChild = 0;
	TiXmlElement* action = 0;
	TiXmlElement* frame = 0;
	TiXmlElement* file = 0;
	TiXmlElement* child = 0;

	if ( ( root = doc.FirstChildElement( "Definition" ) ) != 0 )
	{
		mode = DEFINITION;
	}
	else if ( ( root = doc.FirstChildElement( "Direct" ) ) != 0 )
	{
		mode = DIRECT;
	}
	else
	{
		console->Print( "ERROR: 'Definition' or 'Direct' root element not found.\n" );
		return false;
	}

	SDL_Surface* surface = 0;
	gedString error;

	if ( mode == DEFINITION )
	{
		// The surface.
		surface = LoadSurface( root, &error );
		if ( !surface )	
		{
			console->Print( "Error loading surface: '%s'\n", error.c_str() );
			return false;
		}

		// Walk the tree, and process.
		for( rootChild = root->FirstChildElement();
			 rootChild;
			 rootChild = rootChild->NextSiblingElement() )
		{
			AllInfo allInfo;
			if ( rootChild->Value() == "Sprite" )
			{
				for( action = rootChild->FirstChildElement( "Action" );
					 action;
					 action = action->NextSiblingElement( "Action" ) )
				{
					for( frame = action->FirstChildElement( "Frame" );
						 frame;
						 frame = frame->NextSiblingElement( "Frame" ) )
					{
							CalcAllInfo( frame, &allInfo, surface );
							EncodeSprite( surface, allInfo, console );
					}
				}
			}
			else if ( rootChild->Value() == "Tile" )
			{
				CalcAllInfo( rootChild, &allInfo, surface );
				EncodeTile( surface, allInfo, console );
			}
			else if ( rootChild->Value() == "Font" )
			{
				CalcAllInfo( rootChild, &allInfo, surface );
				EncodeFont( surface, allInfo, console );
			}
			else
			{
				console->Print( "ERROR: Unrecognized element name. (Not Sprite, Tile, or Font.).\n" );
				return false;
			}
			engine->Draw();
		}
		return true;
	}
	else
	{
		for( file = root->FirstChildElement( "File" );
			 file;
			 file = file->NextSiblingElement( "File" ) )
		{
			surface = LoadSurface( file, &error );
			if ( !surface )	
			{
				console->Print( "Error loading surface: '%s'\n", error.c_str() );
				return false;
			}
			scan.Init();

			for( child = file->FirstChildElement();
				 child;
				 child = child->NextSiblingElement() )
			{
				AllInfo allInfo;
				if ( child->Value() == "ColorKey" )
				{
					CalcAllInfo( child, &allInfo, surface );
					EncodeColorKey( surface, allInfo, console );
				}
				else if ( child->Value() == "Image" )
				{
					CalcAllInfo( child, &allInfo, surface );
					if ( allInfo.type == TYPE_SPRITE )
						EncodeSprite( surface, allInfo, console );
					else if ( allInfo.type == TYPE_TILE )
						EncodeTile( surface, allInfo, console );
					else
						console->Print( "ERROR: Direct encoding can not identify whether Sprite or Tile.\n" );
				}
				else
				{
					gedString aux(child->Value());
					console->Print( "ERROR: Unrecognized element name '%s'. (Not ColorKey or Image.).\n", aux.c_str() );
					return false;
				}
				engine->Draw();
			}
		}
		for (	file = root->FirstChildElement( "BinaryFile" );
				file;
				file = file->NextSiblingElement( "BinaryFile" ) )
		{
			EncodeBinary( file, console );
		}
		for (	file = root->FirstChildElement( "TextFile" );
				file;
				file = file->NextSiblingElement( "TextFile" ) )
		{
			EncodeText( file, console );
		}
		return false;
	}
}
コード例 #10
0
ファイル: bone.c プロジェクト: umibps/KABURAGI
void ReadPmxBone(
	PMX_BONE* bone,
	uint8* data,
	PMX_DATA_INFO* info,
	size_t* data_size
)
{
	MEMORY_STREAM stream = {data, 0, (size_t)(info->end - data), 1};
	char *name_ptr;
	size_t bone_index_size = info->bone_index_size;
	int32 int32_value;
	int length;

	// 日本語名
	length = GetTextFromStream((char*)data, &name_ptr);
	stream.data_point = sizeof(int32) + length;
	bone->interface_data.name = EncodeText(info->encoding, name_ptr, length);

	// 英語名
	length = GetTextFromStream((char*)&data[stream.data_point], &name_ptr);
	stream.data_point += sizeof(int32) + length;
	bone->interface_data.english_name = EncodeText(info->encoding, name_ptr, length);

	// 位置
	(void)MemRead(&bone->origin, sizeof(bone->origin), 1, &stream);
	SET_POSITION(bone->origin, bone->origin);
	COPY_VECTOR3(bone->offset_from_parent, bone->origin);
	BtTransformSetOrigin(bone->world_transform, bone->origin);
	
	// 親ボーン
	bone->parent_bone_index = GetSignedValue(&data[stream.data_point], (int)bone_index_size);
	stream.data_point += bone_index_size;

	// レイヤー
	(void)MemRead(&int32_value, sizeof(int32), 1, &stream);
	bone->layer_index = int32_value;

	// フラグ
	(void)MemRead(&bone->flags, sizeof(bone->flags), 1, &stream);
	// 次のボーン有無
	if((bone->flags & PMX_BONE_FLAG_HAS_DESTINATION_ORIGIN) != 0)
	{
		bone->destination_origin_bone_index = GetSignedValue(&data[stream.data_point], (int)bone_index_size);
		stream.data_point += bone_index_size;
	}
	else
	{
		float offset[3];
		(void)MemRead(offset, sizeof(offset), 1, &stream);
		SET_POSITION(bone->destination_origin, offset);
	}
	// バイアスの有無
	if((bone->flags & PMX_BONE_FLAG_HAS_INHERENT_ROTATION) != 0
		|| (bone->flags & PMX_BONE_FLAG_HAS_INHERENT_TRANSLATION) != 0)
	{
		bone->parent_inherent_bone_index = GetSignedValue(&data[stream.data_point], (int)bone_index_size);
		stream.data_point += bone_index_size;
		(void)MemRead(&bone->coefficient, sizeof(bone->coefficient), 1, &stream);
	}
	// 固定軸の有無
	if((bone->flags & PMX_BONE_FLAG_HAS_FIXED_AXIS) != 0)
	{
		(void)MemRead(bone->fixed_axis, sizeof(bone->fixed_axis), 1, &stream);
	}

	// ローカルの軸
	if((bone->flags & PMX_BONE_FLAG_HAS_LOCAL_AXIS) != 0)
	{
		(void)MemRead(bone->axis_x, sizeof(bone->axis_x), 1, &stream);
		SET_POSITION(bone->axis_x, bone->axis_x);
		(void)MemRead(bone->axis_z, sizeof(bone->axis_z), 1, &stream);
		SET_POSITION(bone->axis_z, bone->axis_z);
	}
	// 親ボーンと一緒に変形
	if((bone->flags & PMX_BONE_FLAG_TRANSFORM_BY_EXTERNAL_PARENT) != 0)
	{
		(void)MemRead(&int32_value, sizeof(int32), 1, &stream);
		bone->global_id = int32_value;
	}
	// IK
	if((bone->flags & PMX_BONE_FLAG_HAS_INVERSE_KINEMATICS) != 0)
	{
		IK_UNIT unit;
		int num_links;
		int i;
		bone->effector_bone_index = GetSignedValue(&data[stream.data_point], (int)bone_index_size);
		stream.data_point += bone_index_size;
		(void)MemRead(&unit.num_iterations, sizeof(unit.num_iterations), 1, &stream);
		(void)MemRead(&unit.angle_limit, sizeof(unit.angle_limit), 1, &stream);
		(void)MemRead(&unit.num_constraints, sizeof(unit.num_constraints), 1, &stream);
		bone->num_iteration = unit.num_iterations;
		bone->angle_limit = unit.angle_limit;
		num_links = unit.num_constraints;
		for(i=0; i<num_links; i++)
		{
			PMX_IK_CONSTRAINT *constraint = (PMX_IK_CONSTRAINT*)StructArrayReserve(bone->constraints);
			constraint->joint_bone_index = GetSignedValue(&data[stream.data_point], (int)bone_index_size);
			stream.data_point += bone_index_size;
			constraint->has_angle_limit = data[stream.data_point];
			if(constraint->has_angle_limit != FALSE)
			{
				bone->flags |= PMX_BONE_FLAG_HAS_ANGLE_LIMIT;
			}
			stream.data_point++;
			if(constraint->has_angle_limit != FALSE)
			{
				float lower[3], upper[3];
				(void)MemRead(lower, sizeof(lower), 1, &stream);
				(void)MemRead(upper, sizeof(upper), 1, &stream);
				PmxBoneGetPositionFromIkUnit(lower, upper,
					constraint->lower_limit, constraint->upper_limit);
			}
		}
	}

	*data_size = stream.data_point;
}