public void RenderHair(Character entity, Matrix4 modelViewMatrix, Matrix4 projection) { if (entity == null || entity.Hairs.Count == 0) return; // Calculate lighting var shader = setupEntityLight(entity, modelViewMatrix, true); for (var h = 0; h < entity.Hairs.Count; h++) { // First: Head attachment var globalHead = (Matrix4)(entity.Transform * entity.Bf.BoneTags[(int)entity.Hairs[h].OwnerBody].FullTransform); var globalAttachment = globalHead.MultiplyByTransform(entity.Hairs[h].OwnerBodyHairRoot); var matrixCount = 10; var hairModelToGlobalMatrices = Helper.RepeatValue(16, () => new float[matrixCount]); unsafe { var tmp = modelViewMatrix * globalAttachment; fixed (float* ptr = &hairModelToGlobalMatrices[0][0]) Helper.PointerCopy(&tmp.Row0.X, ptr, 16); } // Then: Individual hair pieces for (var i = 0; i < entity.Hairs[h].Elements.Count; i++) { StaticFuncs.Assert(i + 1 < matrixCount); /* * Definitions: x_o - as in original file. x_h - as in hair model * (translated) * M_ho - translation matrix. x_g = global position (before modelview) * M_go - global position * * We know: * x_h = M_ho * x_o * x_g = M_go * x_o * We want: * M_hg so that x_g = M_gh * x_m * We have: M_oh, M_g * * x_h = M_ho * x_o => x_o = M_oh^-1 * x_h * x_g = M_go * M_ho^-1 * x_h * (M_ho^-1 = M_oh so x_g = M_go * M_oh * x_h) */ var invOriginToHairModel = new Transform(); invOriginToHairModel.SetIdentity(); // Simplification: Always translation matrix, no invert needed invOriginToHairModel.Origin -= entity.Hairs[h].Elements[i].Position; var globalFromHair = entity.Hairs[h].Elements[i].Body.GetWorldTransform().MultiplyByTransform(invOriginToHairModel); unsafe { var tmp = modelViewMatrix * globalFromHair; fixed (float* ptr = &hairModelToGlobalMatrices[i + 1][0]) Helper.PointerCopy(&tmp.Row0.X, ptr, 16); } } unsafe { fixed (float* ptr = &hairModelToGlobalMatrices[0][0]) GL.UniformMatrix4(shader.ModelView, entity.Hairs[h].Elements.Count + 1, false, ptr); } GL.UniformMatrix4(shader.Projection, false, ref projection); RenderMesh(entity.Hairs[h].Mesh); } }
public void Prepare() { ID = 0; Name = ""; Type = 0; Meshes = new List<BaseMesh>(); Sprites = new List<Sprite>(); Rooms = new List<Room>(); FlipData = new List<FlipInfo>(); Textures = new List<uint>(); EntityTree = new Dictionary<uint, Entity>(); ItemsTree = new Dictionary<uint, BaseItem>(); Character = null; #if !NO_AUDIO AudioSources = new List<AudioSource>(); AudioBuffers = new uint[0]; AudioEffects = new List<AudioEffect>(); AudioEmitters = new List<AudioEmitter>(); AudioMap = new List<short>(); StreamTracks = new List<StreamTrack>(); StreamTrackMap = new List<byte>(); #endif AnimSequences = new List<AnimSeq>(); RoomBoxes = new List<RoomBox>(); CamerasSinks = new List<StatCameraSink>(); SkeletalModels = new List<SkeletalModel>(); SkyBox = null; AnimCommands = new short[0]; }
public void Empty() { LastContainer = null; EngineLua.ClearTasks(); #if !NO_AUDIO Audio.DeInit(); // De-initialize and destroy all audio objects. #endif if(MainInventoryManager != null) { MainInventoryManager.SetInventory(null); MainInventoryManager.SetItemsType(MenuItemType.Supply); // see base items } if(Character != null) { Character.Self.Room = null; Character.CurrentSector = null; } EntityTree.Clear(); // Clearing up entities must happen before destroying rooms. // Destroy Bullet's MISC objects (debug spheres etc.) // FIXME: Hide it somewhere, it is nasty being here. if(BtEngineDynamicsWorld != null) { for(var i = BtEngineDynamicsWorld.NumCollisionObjects - 1; i >= 0; i--) { var obj = BtEngineDynamicsWorld.CollisionObjectArray[i]; RigidBody body; if((body = obj as RigidBody) != null) { var cont = (EngineContainer) body.UserObject; body.UserObject = null; if(cont != null && cont.ObjectType == OBJECT_TYPE.BulletMisc) { if(body.MotionState != null) { body.MotionState.Dispose(); body.MotionState = null; } //body.CollisionShape = null; BtEngineDynamicsWorld.RemoveRigidBody(body); cont.Room = null; cont = null; body.Dispose(); body = null; } } } } foreach(var room in Rooms) { room.Empty(); } Rooms.Clear(); FlipData.Clear(); RoomBoxes.Clear(); CamerasSinks.Clear(); Sprites.Clear(); ItemsTree.Clear(); Character = null; SkeletalModels.Clear(); Meshes.Clear(); GL.DeleteTextures(Textures.Count, Textures.ToArray()); Textures.Clear(); TextureAtlas = null; AnimSequences.Clear(); }
public void PerfomOnFrame(Character ent, SSAnimation ssAnim, ENTITY_ANIM state) { OnFrame(ent, ssAnim, state); }