public WhBone(WhModel model, int index, BinaryReader r) { Model = model; Index = index; KeyId = r.ReadInt32(); Flags = r.ReadUInt32(); Parent = r.ReadInt16(); Mesh = r.ReadUInt16(); Id = r.ReadUInt32(); Pivot = new Vec3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); Translation = WhAnimatedVec3.ReadSet(r); Rotation = WhAnimatedQuat.ReadSet(r); Scale = WhAnimatedVec3.ReadSet(r); Hidden = false; Updated = false; // Не стал делать //self.transformedPivot = vec3.create(); //self.matrix = mat4.create(); //self.tmpVec = vec3.create(); //self.tmpQuat = quat.create(); //self.tmpMat = mat4.create(); // Я сделал. -1 значит что эта переменная будет игнорироваться при Update модели IndexInParentModel = -1; }
public static WhAnimatedVec3[] ReadSet(BinaryReader r) { var count = r.ReadInt32(); var data = new WhAnimatedVec3[count]; for (var i = 0; i < count; i++) { data[i] = new WhAnimatedVec3(r); } return(data); }
public void Update(int time) { if (Hidden) { Hide(); return; } if (Updated || SkipUpdate) { return; } Updated = true; if (Model == null || Model.Animations == null || Model.AnimPaused) { return; } //mat4.identity(self.matrix); var anim = Model.CurrentAnimation; if (anim == null) { return; } var billboard = (Flags & 8) != 0; var transUsed = WhAnimatedVec3.IsUsed(Translation, anim.Index); var rotUsed = WhAnimatedQuat.IsUsed(Rotation, anim.Index); var scaleUsed = WhAnimatedVec3.IsUsed(Scale, anim.Index); if (transUsed || rotUsed || scaleUsed || billboard) { //mat4.translate(self.matrix, self.matrix, self.pivot); if (transUsed) { // Запоминаю текущий translation вместо модификации матрицы (как в оригинале) LastUpdatedTranslation = WhAnimatedVec3.GetValue(Translation, anim.Index, time); //Wow.AnimatedVec3.getValue(self.translation, anim.index, time, self.tmpVec); //mat4.translate(self.matrix, self.matrix, self.tmpVec) } if (rotUsed) { // Запоминаю текущий rotation вместо модификации матрицы (как в оригинале) // mat4.fromQuat + mat4.transpose (создать матрицу из квартерниона и инвертировать ее) это то же самое что инверт квартерниона, а затем создание матрицы из полученного квартерниона // но так как я матрицы не использую, я просто инвертирую квартернион и сохраняю его LastUpdatedRotation = Quat.Invert(WhAnimatedQuat.GetValue(Rotation, anim.Index, time)); //Wow.AnimatedQuat.getValue(self.rotation, anim.index, time, self.tmpQuat); //mat4.fromQuat(self.tmpMat, self.tmpQuat); //mat4.transpose(self.tmpMat, self.tmpMat); //mat4.multiply(self.matrix, self.matrix, self.tmpMat) } if (scaleUsed) { // Запоминаю текущий scale вместо модификации матрицы (как в оригинале) LastUpdatedScale = WhAnimatedVec3.GetValue(Scale, anim.Index, time); //Wow.AnimatedVec3.getValue(self.scale, anim.index, time, self.tmpVec); //mat4.scale(self.matrix, self.matrix, self.tmpVec) } if (billboard) { //var yRot = -self.model.renderer.zenith + Math.PI / 2; //var zRot; //if (self.model.model.type == Wow.Types.ITEM) //{ // zRot = self.model.renderer.azimuth - Math.PI // } //else //{ // zRot = self.model.renderer.azimuth - Math.PI * 1.5 // } //mat4.identity(self.matrix); //mat4.translate(self.matrix, self.matrix, self.pivot); //mat4.rotateZ(self.matrix, self.matrix, zRot); //mat4.rotateY(self.matrix, self.matrix, yRot) } //mat4.translate(self.matrix, self.matrix, vec3.negate(self.tmpVec, self.pivot)) } if (Parent > -1) { Model.Bones[Parent].Update(time); // По сути это значит что translation/rotation/scale которые в этой кости вычеслены будут являться локальными и чтобы получить глобальные, // нужно учесть еще из parent кости тоже //mat4.multiply(self.matrix, self.model.bones[self.parent].matrix, self.matrix) } //vec3.transformMat4(self.transformedPivot, self.pivot, self.matrix) }