private RootEntity ParseHMDEntities(BinaryReader reader) { var rootEntity = new RootEntity(); var mapFlag = reader.ReadUInt32(); var primitiveHeaderTop = reader.ReadUInt32() * 4; var blockCount = reader.ReadUInt32(); var modelEntities = new List <ModelEntity>(); for (var i = 0; i < blockCount; i++) { var primitiveSetTop = reader.ReadUInt32() * 4; if (primitiveSetTop == 0) { continue; } var blockTop = reader.BaseStream.Position; reader.BaseStream.Seek(_offset + primitiveSetTop, SeekOrigin.Begin); ProccessPrimitive(reader, modelEntities, i); reader.BaseStream.Seek(blockTop, SeekOrigin.Begin); } var coordCount = reader.ReadUInt32(); for (var c = 0; c < coordCount; c++) { Matrix4 localMatrix = ReadCoord(reader); modelEntities[c].LocalMatrix = localMatrix; } foreach (var modelEntity in modelEntities) { modelEntity.ParentEntity = rootEntity; } rootEntity.ChildEntities = modelEntities.ToArray(); rootEntity.ComputeBounds(); return(rootEntity); }
private void ProcessAnimationObject(AnimationObject animationObject, int frameIndex, Matrix4?parentMatrix, AnimationObject selectedAnimationObject = null, RootEntity selectedEntity = null) { var animationFrames = animationObject.AnimationFrames; var totalFrames = animationFrames.Count; var localMatrix = Matrix4.Identity; for (var f = 0; f <= frameIndex && f < totalFrames; f++) { if (!animationFrames.ContainsKey(f)) { continue; } var matrix = Matrix4.Identity; var sumFrame = animationFrames[f]; if (sumFrame.Rotation != null) { var r = Matrix4.CreateFromQuaternion(sumFrame.Rotation.Value); matrix = matrix * r; } else if (sumFrame.EulerRotation != null) { var r = GeomUtils.CreateR(sumFrame.EulerRotation.Value); matrix = matrix * r; } if (sumFrame.Scale != null) { var scale = (Vector3)sumFrame.Scale; var s = GeomUtils.CreateS(scale.X); matrix = matrix * s; } if (sumFrame.Translation != null) { var translation = (Vector3)sumFrame.Translation; var t = GeomUtils.CreateT(translation); matrix = matrix * t; } var absoluteMatrixValue = sumFrame.AbsoluteMatrix; if (!absoluteMatrixValue) { matrix = matrix * localMatrix; } localMatrix = matrix; } Matrix4 worldMatrix; if (parentMatrix != null) { worldMatrix = localMatrix * parentMatrix.Value; _scene.SkeletonBatch.AddLine(Vector3.TransformPosition(Vector3.One, parentMatrix.Value), Vector3.TransformPosition(Vector3.One, worldMatrix), animationObject == selectedAnimationObject ? Color.Blue : Color.Red); } else { worldMatrix = localMatrix; } if (selectedEntity != null) { var objectId = animationObject.TMDID.GetValueOrDefault(); if (objectId > 0) { var models = selectedEntity.GetModelsWithTMDID(objectId - 1); foreach (var model in models) { _scene.MeshBatch.BindModelBatch(model, _animationProcessIndex++, worldMatrix, _scene.TextureBinder); } } } foreach (var childObject in animationObject.Children) { ProcessAnimationObject(childObject, frameIndex, worldMatrix, selectedAnimationObject, selectedEntity); } }
public void SetupAnimationFrame(int frame, AnimationObject animationObject = null, RootEntity selectedEntity = null) { _scene.SkeletonBatch.Reset(); _animationProcessIndex = 0; ProcessAnimationObject(_animation.RootAnimationObject, frame, null, animationObject, selectedEntity); }
private RootEntity ParsePMD(BinaryReader reader) { var primPoint = reader.ReadUInt32(); var vertPoint = reader.ReadUInt32(); var nObj = reader.ReadUInt32(); if (nObj < 1 || nObj > 4000) { return(null); } var models = new List <ModelEntity>(); for (var o = 0; o < nObj; o++) { var model = new ModelEntity(); var triangles = new List <Triangle>(); var nPointers = reader.ReadUInt32(); if (nPointers < 1 || nPointers > 4000) { return(null); } for (var p = 0; p < nPointers; p++) { var position = reader.BaseStream.Position; var pointer = reader.ReadUInt32(); reader.BaseStream.Seek(_offset + pointer, SeekOrigin.Begin); var nPacket = reader.ReadUInt16(); if (nPacket > 4000) { return(null); } var primType = reader.ReadUInt16(); if (primType > 15) { return(null); } for (var pk = 0; pk < nPacket; pk++) { switch (primType) { case 0x00: triangles.Add(ReadPolyFT3(reader)); break; case 0x01: triangles.AddRange(ReadPolyFT4(reader)); break; case 0x02: triangles.Add(ReadPolyGT3(reader)); break; case 0x03: triangles.AddRange(ReadPolyGT4(reader)); break; case 0x04: triangles.Add(ReadPolyF3(reader)); break; case 0x05: triangles.AddRange(ReadPolyF4(reader)); break; case 0x06: triangles.Add(ReadPolyG3(reader)); break; case 0x07: triangles.AddRange(ReadPolyG4(reader)); break; case 0x08: triangles.Add(ReadPolyFT3(reader, true, _offset + vertPoint)); break; case 0x09: triangles.AddRange(ReadPolyFT4(reader, true, _offset + vertPoint)); break; case 0x0a: triangles.Add(ReadPolyGT3(reader, true, _offset + vertPoint)); break; case 0x0b: triangles.AddRange(ReadPolyGT4(reader, true, _offset + vertPoint)); break; case 0x0c: triangles.Add(ReadPolyF3(reader, true, _offset + vertPoint)); break; case 0x0d: triangles.AddRange(ReadPolyF4(reader, true, _offset + vertPoint)); break; case 0x0e: triangles.Add(ReadPolyG3(reader, true, _offset + vertPoint)); break; case 0x0f: triangles.AddRange(ReadPolyG4(reader, true, _offset + vertPoint)); break; default: goto EndObject; } } reader.BaseStream.Seek(position + 4, SeekOrigin.Begin); } EndObject: model.Triangles = triangles.ToArray(); models.Add(model); } EndModel: if (models.Count > 0) { var entity = new RootEntity(); foreach (var model in models) { model.ParentEntity = entity; } entity.ChildEntities = models.ToArray(); entity.ComputeBounds(); return(entity); } return(null); }
public void SetupMultipleEntityBatch(RootEntity[] checkedEntities = null, ModelEntity selectedModelEntity = null, RootEntity selectedRootEntity = null, TextureBinder textureBinder = null, bool updateMeshData = true, bool focus = false, bool hasAnimation = false) { if (selectedModelEntity == null && selectedRootEntity == null) { return; } var bounds = focus ? new BoundingBox() : null; selectedRootEntity = selectedRootEntity ?? selectedModelEntity.GetRootEntity(); //count the selected entity var modelCount = 1; //count checked, excecpt, the selected if (checkedEntities != null) { foreach (var checkedEntity in checkedEntities) { if (checkedEntity == selectedRootEntity) { continue; } modelCount += checkedEntity.ChildEntities.Length; if (focus) { bounds.AddPoints(checkedEntity.Bounds3D.Corners); } } } //focus if (selectedRootEntity != null) { foreach (var subEntity in selectedRootEntity.ChildEntities) { modelCount++; if (focus) { bounds.AddPoints(subEntity.Bounds3D.Corners); } } } //reset ResetModelIndex(); if (updateMeshData) { Reset(modelCount); } //bindings //checked entities, except selected root if (checkedEntities != null) { foreach (var entity in checkedEntities) { if (entity == selectedRootEntity) { continue; } foreach (ModelEntity modelEntity in entity.ChildEntities) { BindMesh(modelEntity, modelEntity.TempMatrix * modelEntity.WorldMatrix, textureBinder, updateMeshData, modelEntity.InitialVertices, modelEntity.InitialNormals, modelEntity.FinalVertices, modelEntity.FinalNormals, modelEntity.Interpolator); } } } //if not animating //if (!hasAnimation) //{ //root entity if (selectedRootEntity != null) { foreach (ModelEntity modelEntity in selectedRootEntity.ChildEntities) { BindMesh(modelEntity, modelEntity.TempMatrix * modelEntity.WorldMatrix, textureBinder, updateMeshData, modelEntity.InitialVertices, modelEntity.InitialNormals, modelEntity.FinalVertices, modelEntity.FinalNormals, modelEntity.Interpolator); } } //} // do focus if (focus) { _scene.FocusOnBounds(bounds); } }
public void SetupMultipleEntityBatch(RootEntity[] checkedEntities = null, ModelEntity selectedModel = null, RootEntity selectedEntity = null, TextureBinder textureBinder = null, bool updateMeshData = true, bool focus = false) { var bounds = focus ? new BoundingBox() : null; var modelCount = checkedEntities != null || selectedEntity != null || selectedModel != null ? 1 : 0; if (checkedEntities != null) { foreach (var entity in checkedEntities) { if (entity == selectedEntity) { continue; } modelCount += entity.ChildEntities.Length; } } if (selectedEntity != null) { foreach (var subEntity in selectedEntity.ChildEntities) { modelCount++; if (focus) { bounds.AddPoints(subEntity.Bounds3D.Corners); } } } if (updateMeshData) { Reset(modelCount); } var modelIndex = 0; if (checkedEntities != null) { foreach (var entity in checkedEntities) { if (entity == selectedEntity) { continue; } foreach (var subEntity in entity.ChildEntities) { if (subEntity == selectedModel) { continue; } BindMesh((ModelEntity)subEntity, modelIndex++, null, textureBinder, updateMeshData); } } } if (selectedEntity != null) { foreach (var subEntity in selectedEntity.ChildEntities) { if (subEntity == selectedModel) { continue; } BindMesh((ModelEntity)subEntity, modelIndex++, null, textureBinder, updateMeshData); } } if (selectedModel != null) { BindMesh(selectedModel, modelIndex, null, textureBinder, updateMeshData); } if (focus) { _scene.FocusOnBounds(bounds); } }