YSRESULT YsWavFile::ConvertToMono(void) { if(YSTRUE==stereo) { const size_t bytePerSample=bit/8; const size_t bytePerTimeStep=2*bytePerSample; const size_t nTimeStep=sizeInBytes/bytePerTimeStep; const size_t newSize=nTimeStep*bytePerSample; unsigned char *newDat=(0<newSize ? new unsigned char [newSize] : NULL); if(NULL!=newDat) { for(size_t ts=0; ts<nTimeStep; ts++) { const int newValue=(GetSignedValue(ts,0)+GetSignedValue(ts,1))/2; unsigned char *const newTimeStepPtr=newDat+ts*bytePerSample; SetSignedValue(newTimeStepPtr,newValue); } delete [] dat; dat=newDat; sizeInBytes=newSize; stereo=YSFALSE; return YSOK; } } return YSERR; }
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; }
YSRESULT YsWavFile::Resample(int newRate) { if(rate!=newRate) { const size_t nChannel=(YSTRUE==stereo ? 2 : 1); const size_t bytePerSample=bit/8; const size_t bytePerTimeStep=nChannel*bytePerSample; const size_t curNTimeStep=sizeInBytes/bytePerTimeStep; const size_t newNTimeStep=curNTimeStep*newRate/rate; const size_t newSize=newNTimeStep*bytePerTimeStep; unsigned char *newDat=(0<newSize ? new unsigned char [newSize] : NULL); if(NULL!=newDat) { for(size_t ts=0; ts<newNTimeStep; ts++) { double oldTimeStepD=(double)curNTimeStep*(double)ts/(double)newNTimeStep; size_t oldTimeStep=(size_t)oldTimeStepD; double param=fmod(oldTimeStepD,1.0); unsigned char *newTimeStepPtr=newDat+ts*bytePerTimeStep; for(size_t ch=0; ch<nChannel; ++ch) { if(curNTimeStep-1<=oldTimeStep) { const int value=GetSignedValue(curNTimeStep-1,ch); SetSignedValue(newTimeStepPtr+bytePerSample*ch,value); } else if(0==oldTimeStep || curNTimeStep-2<=oldTimeStep) { const double value[2]= { (double)GetSignedValue(oldTimeStep,ch), (double)GetSignedValue(oldTimeStep+1,ch) }; const int newValue=(int)(value[0]*(1.0-param)+value[1]*param); SetSignedValue(newTimeStepPtr+bytePerSample*ch,newValue); } else { const double v[4]= { (double)GetSignedValue(oldTimeStep-1,ch), // At x=-1.0 (double)GetSignedValue(oldTimeStep,ch), // At x= 0.0 (double)GetSignedValue(oldTimeStep+1,ch), // At x= 1.0 (double)GetSignedValue(oldTimeStep+2,ch) // At x= 2.0 }; // Cubic interpolation. Linear didn't work well. // axxx+bxx+cx+d=e // x=-1 -> -a+b-c+d=v0 (A) // x= 0 -> d=v1 (B) // x= 1 -> a+b+c+d=v2 (C) // x= 2 -> 8a+4b+2c+d=v3 (D) // // (B) => d=v1; // (A)+(C) => 2b+2d=v0+v2 => b=(v0+v2-2d)/2 // // (D)-2*(B) => 6a+2b-d=v3-2*v2 // => a=(v3-2*v2-2b+d)/6 const double d=v[1]; const double b=(v[0]+v[2]-2.0*d)/2.0; const double a=(v[3]-2.0*v[2]-2.0*b+d)/6.0; const double c=v[2]-a-b-d; double newValue=a*param*param*param +b*param*param +c*param +d; SetSignedValue(newTimeStepPtr+bytePerSample*ch,(int)newValue); } } } } rate=newRate; delete [] dat; dat=newDat; sizeInBytes=newSize; } return YSOK; }
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; }
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; }