Jump to content

CopyEntity and LUA, a relationship doomed?


Flexman
 Share

Recommended Posts

I've been having a little problem with spawning helicopter entities and the LUA for these helicopters. I'll try and relate what happens here as best I can in case one of you much smarter folks can spot anything.

 

This is a BMax to LUA problem I think.

 

Description of problem

 

Apache helicopters use LUA to load the rotor model, control lights, door animations, animate rotors. All spawned Apaches process the update loop correctly. You can use as an example: PlayerVehicle.SetKey("rotorspeed","4.5") to set the rotors turn at 4.5 degrees every update. It works fine.

 

Problem comes with READING values though GetKey(). It will only work for entities loaded via LoadScene(), which is the first Apache. The Apache is copied, dressed with other data and loaded munitions in BMax, then the original is dumped. All spawned entities after that are created using CopyEntity() and CopyKeys(). while SetKey() works on these, GetKey() will always return an empty string. Even putting a Print("HEY GETKEY HAS BEEN CALLED") after the function isn't processed on these kinds of spawned entities.

 

From what I understand, LoadModel() loads the LUA and must do some magic to ties that instance of the entity to the LUA state. But this isn't happening with CopyEntity()?

 

Given that SetKey() works on these entities but GetKey() does not for copied entities, even when it's a simple Print() statement, what is going on here do you think?

6600 2.4G / GTX 460 280.26 / 4GB Windows 7

Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT

Tricubic Studios Ltd. ~ Combat Helo

Link to comment
Share on other sites

I think I must be missing something from what you are trying to do, Flexman, because I can use GetKeys on a copied entity and get all of its keys. I must be missing something from what you are trying to do...

 

Framework leadwerks.engine
Import "c:\program files\leadwerks engine sdk 2.31\bmx\framework\framework.bmx"
Include "lua-gluefunctions.bmx"
GCSetMode(2)

RegisterAbstractPath ("c:\program files\leadwerks engine sdk 2.31")
Graphics(800, 600)

Global fw:TFramework = CreateFramework()
If Not fw RuntimeError "Failed to initialize engine."
SetScriptObject("fw", fw)

MoveEntity(fw.Main.camera, Vec3(1.5, 0, - 2))

Global model:TEntity = LoadModel("abstract::environment_corona.gmf")
Global modelcopy:TEntity[3]
Global count:Int = 0
HideMouse()
Repeat
       If KeyHit(KEY_ESCAPE) Exit
       If AppTerminate() Exit

       fw.Update()
       fw.Render()

If KeyHit(KEY_SPACE) And count < 3
	modelcopy[count] = CopyEntity(model, 1)
	CopyEntityKeys(model, modelcopy[count])
	PositionEntity(modelcopy[count], Vec3(1 + count, 0, 0), 1)
	FreeEntity(model)
	model = modelcopy[count]
	count = count + 1
	GCCollect()
End If

GetAllCopiedKeys(model)

       Flip(0)
Forever
GCCollect()
End

Function GetAllCopiedKeys(entity:TEntity)
SetBlend(1)
Local i:Int = 0
Local mcpos:TVec3 = CameraUnproject(fw.Main.camera, EntityPosition(entity, 1))
For key:String = EachIn entity.keys.keys()
	i = i + 20
	DrawText(key + ": " + GetEntityKey(entity, key), mcpos.x, mcpos.y + i)
Next
SetBlend(0)
End Function

Function SetScriptObject(name:String, o:Object)
       Local size:Int=GetStackSize()
       lua_pushbmaxobject(luastate.L, o)
       lua_setglobal(luastate.L,name)
       SetStackSize(size)
EndFunction

Function GetStackSize:Int()
       Return lua_gettop(luastate.L)
EndFunction

Function SetStackSize(size:Int)
       Local currentsize:Int=GetStackSize()
       If size<currentsize
       lua_pop(luastate.L,currentsize-size)
       EndIf
EndFunction

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Thanks for looking Mac.

 

All I really want for now is to be able to find "rotor_limb_1" from BMax on a model named "rotor_mast.gmf" loaded in the Apache LUA script and parented to the Apache model. But GetKey() not working is very strange.

 

It must be something I've cocked up somewhere. I'll try to explain what's going on.

 

I use LoadScene() and starting Apache aircraft are placed on the map as needed.

During a ProcessScene() function, bit of a relic but handy, I replace these Apache entities with a new one. e is the current entity

 

			' CONSTRUCT A PLAYER FRIENDLY APACHE LONGBOW ENTITY'
		If(vh = "AH64D") Then
			vh = ""
			CreateApacheEntity(EntityPosition(e), EntityRotation(e), e)
			FreeEntity(e) ;
			GCCollect()
			done = 0;
			Exit;
		End If

 

And here's CreateApacheEntity()

Function CreateApacheEntity(loc:TVec3 = Null, rot:TVec3 = Null, srcent:TEntity = Null)
Local helo:THelicopter = New THelicopter;
Local idString:String

idString = String("LONGBOW00" + game.HelicopterCount)

helo.Load3DModels(srcent) ;

If Not helo.entity
	AppLog(" *** CreateApacheEntity:NO ENTITY:")
Else

	' COPY KEYS FROM EDITOR OR SOURCE AS NECESSARY'
	If srcent Then
		CopyEntityKeys(srcent, helo.entity) ;
		helo.entity.SetKey("fcr", GetEntityKey(srcent, "fcr", "1").ToString())
		helo.entity.SetKey("rotorspeed", GetEntityKey(srcent, "rotorspeed", "0").ToString())
		helo.entity.SetKey("stabpos", GetEntityKey(srcent, "stabpos", "0").ToString())
	End If
End If

AppLog(" *** CreateApacheEntity:Crewcount:" + GetEntityKey( helo.entity,"crewcount") + " *** ") ;
AppLog(" *** CreateApacheEntity:Crewslotname:" + helo.entity.GetKey("slotname_1") + " *** ") ;

' IN LUA, SLOTS ARE INDEXED FROM 1, IN BMAX THEY ARE INDEXED FROM ZERO'
helo.PlayerSlots = Int(helo.entity.GetKey("crewcount", 0))
helo.CrewSlot = New TVehicleSlots[helo.PlayerSlots] ;
For Local n:Int = 0 To helo.PlayerSlots - 1
		helo.CrewSlot[n] = New TVehicleSlots
		helo.CrewSlot[n].Pos = New TVec3
		AppLog(" *** Crewslotname: " + helo.entity.GetKey("slotname_" + String(n + 1), "") + " *** ") ;
		helo.CrewSlot[n].name = String(helo.entity.GetKey("slotname_" + String(n + 1), "slotname_" + (n + 1)))
		helo.CrewSlot[n].Pos = StringToVec3(helo.entity.GetKey("crewslot_" + String(n + 1), "0,0,0"))
Next
AppLog(helo.PlayerSlots + " CrewSlots Initialised")

helo.idString = idString
helo.childTADSpieExternal = helo.entity.FindChild("tads_pie")


If loc <> Null
	PositionEntity(helo.body, loc) ;
	RotateEntity(helo.body, rot) ;
Else
	PositionEntity(helo.body, game.scene.campos) ;
	RotateEntity(helo.body, Vec3(0)) ;
End If

SetEntityCallback(helo.entity, helo.MessageReceiveCallback, ENTITYCALLBACK_MESSAGERECEIVE) ;
game.AddHelo(idString, helo) ;

SetEntityKey(helo.entity, "vehicle", VEHICLE_KEY_APACHE_LONGBOW) ;
SetEntityKey(helo.entity, "action", ACTION_MOUNT) ;
SetEntityKey(helo.entity, "guid", idString) ;
DebugLog("   CreateApacheEntity :" + idString) ;

helo.SoundIdle = LoadSound("abstract::AH64CompressorIn.ogg") ;
helo.SourceIdle = CreateSource(helo.SoundIdle, SOURCE_EAX | (SOURCE_LOOP)) ;
SetSourcePosition(helo.SourceIdle, EntityPosition(helo.body)) ;

helo.SoundRotors = LoadSound("abstract::apache_noise_internal.ogg") ;
helo.SourceRotors = CreateSource(helo.SoundRotors, SOURCE_EAX | (SOURCE_LOOP)) ;
SetSourcePosition(helo.SourceRotors, EntityPosition(helo.entity)) ;

SetSourceVolume(helo.SourceIdle, 0.0) ;
SetSourceRange(helo.SourceIdle, 60.0) ;

SetSourceVolume(helo.SourceRotors, 0.0) ;
SetSourceRange(helo.SourceRotors, 60.0) ;

PlaySource(helo.SourceIdle) ;
PlaySource(helo.SourceRotors) ;

End Function

 

 

The final part is the Load3DModels function...which is called early in CreateApacheEntity() Here I tried all manner of CopyEntity() etc. And I've since changed it back to what it was originally, which results in the same behavior. GetKey() not working. Maybe there's a LUA issue not being picked up.

 

Method Load3DModels(srcEntity:TEntity)

	Self.model = LoadModel("abstract::aircraft_helicopter_ah64d.gmf") ;
	Self.entity = Self.model
	Self.body = TBody(Self.model) ;

	Self.entity.Show()
	Self.body.SetCollisionType(3, 1) ;
	Self.ViewPivot.SetParent(Self.entity) ;

	' STORES - WEAPONS PODS'
	Self.Stores.Initialise(TModel(Self.model)) ;
	Self.Stores.SetPylon(1, PYLON_HELLFIRE) ;
	Self.Stores.SetPylon(2, PYLON_HELLFIRE) ;
	Self.Stores.SetPylon(0, PYLON_ROCKET) ;
	Self.Stores.SetPylon(3, PYLON_ROCKET) ;

End Method

6600 2.4G / GTX 460 280.26 / 4GB Windows 7

Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT

Tricubic Studios Ltd. ~ Combat Helo

Link to comment
Share on other sites

I trimmed down your code and converted it to something I could try to reproduce, but as you can see its basically your code. I still get the keys from the copied entity using getkeys... which makes me think that maybe its an issue with the script?

 

Framework leadwerks.engine
Import "c:\program files\leadwerks engine sdk\bmx\framework\framework.bmx"
Include "lua-gluefunctions.bmx"
GCSetMode(2)
RegisterAbstractPath ("c:\program files\leadwerks engine sdk")
Graphics(800, 600)
Global fw:TFramework = CreateFramework()
If Not fw RuntimeError "Failed to initialize engine."
SetScriptObject("fw", fw)

MoveEntity(fw.Main.camera, Vec3(1.5, 0, - 2))
Global light:TLight = CreateDirectionalLight()
RotateEntity(light, Vec3(45, 45, 45), 1)
Global e:TModel = LoadModel("abstract::environment_corona.gmf")
Global done:Int = 0

HideMouse()
Repeat
   If KeyHit(KEY_ESCAPE) Exit
   If AppTerminate() Exit

   fw.Update()
   fw.Render()

   If KeyHit(KEY_SPACE)
If done = 0
          done = 1
   CreateApacheEntity(EntityPosition(e), EntityRotation(e), e)
          FreeEntity(e)
          GCCollect()
End If
   End If

   Flip(0)
Forever
GCCollect()
End

Function CreateApacheEntity(loc:TVec3 = Null, rot:TVec3 = Null, srcent:TEntity = Null)
   Local helo:THelicopter = New THelicopter
   helo.Load3DModels(srcent)
   PositionEntity(helo.entity, Vec3(2, 0, 0), 1)
   If Not helo.entity
   	AppLog(" *** CreateApacheEntity:NO ENTITY:")
   Else
       If srcent Then
          CopyEntityKeys(srcent, helo.entity)
          helo.entity.SetKey("fcr", GetEntityKey(srcent, "fcr", "1").ToString())
       End If
   End If
       AppLog(" *** CreateApacheEntity:FCR:" + GetEntityKey(helo.entity, "fcr") + " *** ")
       AppLog(" *** CreateApacheEntity:Material:" + GetEntityKey(helo.entity, "material") + " *** ")
       AppLog(" *** CreateApacheEntity:Radius:" + helo.entity.GetKey("radius") + " *** ")
End Function

Type THelicopter
Field model:TModel
Field entity:TEntity

Method Load3DModels(srcEntity:TEntity)
           'Self.model = LoadModel("abstract::environment_corona.gmf")'
    Self.model = LoadModel("abstract::firepit.gmf")
           Self.entity = Self.model
       End Method
End Type

Function SetScriptObject(name:String, o:Object)
   Local size:Int = GetStackSize()
   lua_pushbmaxobject(luastate.L, o)
   lua_setglobal(luastate.L, name)
   SetStackSize(size)
EndFunction

Function GetStackSize:Int()
   Return lua_gettop(luastate.L)
EndFunction

Function SetStackSize(size:Int)
   Local currentsize:Int = GetStackSize()
   If size < currentsize
   	lua_pop(luastate.L, currentsize - size)
   EndIf
EndFunction

 

EDIT---i take it back... if you run this code, you will see that it doesn't get the value for the material... it gets the radius from GetKey and it gets the FCR value from SetKey... but not the material.... hmmm...

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Ok it looks like CopyEntityKeys() doesn't overwrite existing keys, but it will write keys to an entity if it doesn't have that key... like the corona's radius is being written to the firepit. But since a material key exists already for the firepit, it will not overwrite it. But it looks like you can use SetKeys to overwrite the copied entity' keys.

 

I guess it depends on how much the lua script is really controlling and whether or not the original entity is the exact same entity as the copied entity or is it just a placeholder for keys? I am assuming its just a placeholder for the keys since you are loading the AH64D model instead of actually just doing a CopyEntity(). I also notice when I do a CopyEntity() instead of a LoadModel() then then it appears to work just fine and I don't need to use a CopyEntityKeys()...

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...