ContainerBridgeCrane
From TrainzOnline
Contents |
Container Bridge Crane
A bridge crane consists of several running parts. This parts are some kind of parented. The hirarchy of this parts look like this:
TBD: Insert hirarchy ... from script comments
Reachable area
The special reacharea parameters for the bridge crane prototype looking like follows:
acts.reacharea-251489 { reacharea.dimension.x 30000 reacharea.dimension.y 100000 reacharea.dimension.z 26000 reacharea.origin_inset.x 15000 reacharea.origin_inset.y 50000 reacharea.origin_inset.z 5000 max_container_count 7 }
Asset files pre version 0.1
The files compile errorless and the messaging runs well. No more functionality implemented and tested in this pre version.
config.txt
kuid <kuid2:215489:110041:1> username "aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1" kind "Scenery" category-class "BU" description "aCTS CONTCRANE Animated Bridge Crane Scenery Utility V0.1" trainz-build 4.6 script "acts_bridgecrane.gs" class "acts_bridgecrane" surveyor-only 0 mesh-table-lod-transition-distances 1000 mesh-detail-level-count 1 kuid-table { scriptinclude <kuid2:215489:110000:1> skinskuid <kuid2:215489:1100200:1> cont10ftsc <kuid2:215489:1100211:1> cont10fthc <kuid2:215489:1100212:1> cont20ftsc <kuid2:215489:1100221:1> cont20fthc <kuid2:215489:1100222:1> cont40ftsc <kuid2:215489:1100231:1> cont40fthc <kuid2:215489:1100232:1> cont45ftsc <kuid2:215489:1100241:1> cont45fthc <kuid2:215489:1100242:1> cont53ftsc <kuid2:215489:1100251:1> cont53fthc <kuid2:215489:1100252:1> } script-include-table { scriptinclude <kuid2:215489:110000:1> skincolor <kuid2:215489:1100200:1> } extensions { reacharea-215489 { cranebase_dimension_x 30000 cranebase_dimension_y 100000 cranebase_dimension_z 26000 cranebase_origin_inset_x 15000 cranebase_origin_inset_y 50000 cranebase_origin_inset_z 5000 max_container_count 7 } } mesh-table { cranebase-lod0 { mesh "acts_cranebase.trainzmesh" auto-create 1 lod-level 0 } bridge-lod0 { mesh "acts_bridge.trainzmesh" auto-create 1 lod-level 0 att-parent "cranebase-lod0" anim "acts_bridge_scene.kin" animation-loop-speed 0.0 critical-animation 0 } trolley-lod0 { mesh "acts_trolley.trainzmesh" auto-create 1 lod-level 0 att "a.bridge" att-parent "bridge-lod0" anim "acts_trolley_scene.kin" animation-loop-speed 0.0 critical-animation 0 } lift-lod0 { mesh "acts_lift.trainzmesh" auto-create 1 lod-level 0 att "a.trolley" att-parent "trolley-lod0" anim "acts_lift_scene.kin" animation-loop-speed 0.0 critical-animation 0 } rotor-lod0 { mesh "acts_rotor.trainzmesh" auto-create 1 lod-level 0 att "a.lift" att-parent "lift-lod0" anim "acts_rotor_scene.kin" animation-loop-speed 0.0 critical-animation 0 } gear-lod0 { mesh "acts_gear.trainzmesh" auto-create 1 lod-level 0 att "a.rotor" att-parent "rotor-lod0" anim "acts_gear_scene.kin" animation-loop-speed 1.0 critical-animation 0 } cont10ftsc-lod0 { mesh "acts_cont_10ftsc.trainzmesh" mesh-asset <kuid2:215489:1100211:1> auto-create 0 lod-level 0 att "a.queue.sccontainer" att-parent "gear-lod0" effects { skincolor10ftsc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont10fthc-lod0 { mesh "acts_cont_10fthc.trainzmesh" mesh-asset <kuid2:215489:1100212:1> auto-create 0 lod-level 0 att "a.queue.hccontainer" att-parent "gear-lod0" effects { skincolor10fthc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont20ftsc-lod0 { mesh "acts_cont_20ftsc.trainzmesh" mesh-asset <kuid2:215489:1100221:1> auto-create 0 lod-level 0 att "a.queue.sccontainer" att-parent "gear-lod0" effects { skincolor20ftsc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont20fthc-lod0 { mesh "acts_cont_20fthc.trainzmesh" mesh-asset <kuid2:215489:1100222:1> auto-create 0 lod-level 0 att "a.queue.hccontainer" att-parent "gear-lod0" effects { skincolor20fthc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont40ftsc-lod0 { mesh "acts_cont_40ftsc.trainzmesh" mesh-asset <kuid2:215489:1100231:1> auto-create 0 lod-level 0 att "a.queue.sccontainer" att-parent "gear-lod0" effects { skincolor40ftsc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont40fthc-lod0 { mesh "acts_cont_40fthc.trainzmesh" mesh-asset <kuid2:215489:1100232:1> auto-create 0 lod-level 0 att "a.queue.hccontainer" att-parent "gear-lod0" effects { skincolor40fthc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont45ftsc-lod0 { mesh "acts_cont_45ftsc.trainzmesh" mesh-asset <kuid2:215489:1100241:1> auto-create 0 lod-level 0 att "a.queue.sccontainer" att-parent "gear-lod0" effects { skincolor45ftsc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont45fthc-lod0 { mesh "acts_cont_45fthc.trainzmesh" mesh-asset <kuid2:215489:1100242:1> auto-create 0 lod-level 0 att "a.queue.hccontainer" att-parent "gear-lod0" effects { skincolor45fthc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont53ftsc-lod0 { mesh "acts_cont_53ftsc.trainzmesh" mesh-asset <kuid2:215489:1100251:1> auto-create 0 lod-level 0 att "a.queue.sccontainer" att-parent "gear-lod0" effects { skincolor53ftsc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } cont53fthc-lod0 { mesh "acts_cont_53fthc.trainzmesh" mesh-asset <kuid2:215489:1100252:1> auto-create 0 lod-level 0 att "a.queue.hccontainer" att-parent "gear-lod0" effects { skincolor53fthc { kind "texture-replacement" texture "acts_container_allinone.texture" } } } } thumbnails { 0 { image "acts_bridgecrane_thumb.jpg" width 240 height 180 } }
acts_bridgecrane.gs
XXX YYY ZZZ
acts_bridgecrane_script.gs
XXX YYY ZZZ
File is located in dispatcher library.
acts_bridgecrane_reachable.gs
include "acts_bridgecrane_globals.gs" include "acts_tools_script.gs" //----------------------------------------------------------------------------- // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_reachable.gs //----------------------------------------------------------------------------- // acts_bridgecrane <-- acts_bridgecrane_script // acts_bridgecrane_script <-- acts_bridgecrane_register // acts_bridgecrane_register <-- acts_bridgecrane_reachable // X acts_bridgecrane_reachable <-- acts_bridgecrane_moving // X acts_bridgecrane_moving <-- acts_bridgecrane_globals // acts_bridgecrane_globals <-- acts_global_values // acts_global_values <-- MapObject //----------------------------------------------------------------------------- class acts_bridgecrane_moving isclass acts_bridgecrane_globals { //--------------------------------------------------------------------------- // Set zeroframe translations for the asset parts //--------------------------------------------------------------------------- int bridge_zeroframe = cranebase_origin_inset_y; int trolley_zeroframe = cranebase_origin_inset_x; int lift_zeroframe = 0; // Scale 1.000..25.000 (cranebase_reacharea_z) int rotor_zeroframe = 900; // Decimal degree -90.0..+90.0 (precision 0.1°) int gear_zeroframe = 2991; // Scale 1.000-2.991-6.058-12.192-13.716-16.154 //--------------------------------------------------------------------------- void moveCranePartsToZeroframe(void) { me.SetMeshAnimationFrame("bridge-lod0", bridge_zeroframe); me.SetMeshAnimationFrame("trolley-lod0", trolley_zeroframe); me.SetMeshAnimationFrame("lift-lod0", lift_zeroframe); me.SetMeshAnimationFrame("rotor-lod0", rotor_zeroframe); me.SetMeshAnimationFrame("gear-lod0", gear_zeroframe); } //--------------------------------------------------------------------------- // TBD: Where and when setting the fitting containers skin? // Asset skins = GetAsset().FindAsset("skinskuid"); // SetFXTextureReplacement("skincolor40ftsc",skins,8); // SetMeshVisible("cont40ftsc-lod0", true); // me.SetMeshAnimationFrame("gear-lod0", 12191.0, 3.0); //--------------------------------------------------------------------------- }; /****************************************************************************** ----------------------------------------------------------------------------- In conjunction with the rotation of the cranearea there ar four cases to know about if a point lies within the reacharea, bounding edges are assumed to be outside. A B B D C A C 0° ≤ w < 90° CD < py < AB and AD < px < BC D B C C A D B D 90° ≤ w < 180° AD < py < BC and AB < px < CD A C D D B A C A 180° ≤ w < 270° AB < py < CD and BC < px < AD B D A A C B D B 270° ≤ w < 360° BC < py < AD and CD < px < AB C ----------------------------------------------------------------------------- *******************************************************************************/ class acts_bridgecrane_reachable isclass acts_bridgecrane_moving { // -------------------------------------------------------------------------- // Loading values from config.txt extensions-219486 cranedata soup // -------------------------------------------------------------------------- void LoadCraneDataInfos(Soup sp) { cranebase_reacharea_x = sp.GetNamedTagAsInt("cranebase_reacharea_x",0); cranebase_reacharea_y = sp.GetNamedTagAsInt("cranebase_reacharea_y",0); cranebase_reacharea_z = sp.GetNamedTagAsInt("cranebase_reacharea_z",0); cranebase_origin_inset_x = sp.GetNamedTagAsInt("cranebase_inset_x",0); cranebase_origin_inset_y = sp.GetNamedTagAsInt("cranebase_inset_y",0); cranebase_origin_inset_z = sp.GetNamedTagAsInt("cranebase_inset_z",0); trolley_bottom_height = sp.GetNamedTagAsInt("trolley_bottom_height",0); lift_bottom_height = sp.GetNamedTagAsInt("lift_bottom_height",0); gear_bottom_height = sp.GetNamedTagAsInt("gear_bottom_height",0); max_container_count = sp.GetNamedTagAsInt("max_container_count",0); } // -------------------------------------------------------------------------- // Returns the vertices of the reacharea rectangle. The insets and dimensions // where deliverd over a objects config extension subsoup. Rotations x and y // are zero. // A---+-----B // | ix | ix insetx, iy insety // |iy-O-----+ dx=AD=BC dimensionx, dy=AB=CD dimensiony // | | | RC[0..3]<=>ABCD // D---+-----C //--------------------------------------------------------------------------- public WorldCoordinate[] GetReachareaCorners() { WorldCoordinate[] RC = new WorldCoordinate[4]; // Reacharea corners ABCD WorldCoordinate OR = me.GetMapObjectPosition(); // Origin of crane OR //------------------------------------------------------------------------- RC[0].baseboardX = OR.baseboardX; RC[0].baseboardY = OR.baseboardY; RC[0].x = OR.x - cranebase_origin_inset_x; RC[0].y = OR.y - cranebase_origin_inset_y; RC[0].z = OR.z; //------------------------------------------------------------------------- RC[1].baseboardX = OR.baseboardX; RC[1].baseboardY = OR.baseboardY; RC[1].x = OR.x - cranebase_origin_inset_x; RC[1].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y; RC[1].z = OR.z; //------------------------------------------------------------------------- RC[2].baseboardX = OR.baseboardX; RC[2].baseboardY = OR.baseboardY; RC[2].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x; RC[2].y = OR.y + cranebase_reacharea_y - cranebase_origin_inset_y; RC[2].z = OR.z; //------------------------------------------------------------------------- RC[3].baseboardX = OR.baseboardX; RC[3].baseboardY = OR.baseboardY; RC[3].x = OR.x + cranebase_reacharea_x - cranebase_origin_inset_x; RC[3].y = OR.y - cranebase_origin_inset_y; RC[3].z = OR.z; //------------------------------------------------------------------------- return RC; } // -------------------------------------------------------------------------- // The two point straight line formulas for x and y for the points A and B: // (by-ay) (bx-ax) // y = ------- * (x-ax) + by x = ------- * (y-ay) + bx // (bx-ax) (by-ay) //--------------------------------------------------------------------------- public float ValueXStraightline( WorldCoordinate P, WorldCoordinate A, WorldCoordinate B) { if (A.y==B.y) return A.y; else return cast<float>((B.x-A.x)*(P.y-A.y)/(B.y-A.y)); return 0.0; } public float ValueYStraightline( WorldCoordinate P, WorldCoordinate A, WorldCoordinate B) { if (A.x==B.x) return A.x; else return cast<float>((B.y-A.y)*(P.x-A.x)/(B.x-A.x)); return 0.0; } // -------------------------------------------------------------------------- // InsideReacharea returns true if the point is reachable, otherwise false. // Edges of the reacharea rectangle are assumed outside. //--------------------------------------------------------------------------- public bool InsideReacharea(WorldCoordinate P, WorldCoordinate[] W) { //------------------------------------------------------------------------- // Adjust the point to the same baseboard as the container crane //------------------------------------------------------------------------- WorldCoordinate SP = actsTools.WCoordAdjustBaseboard(P,me.GetMapObjectPosition()); //------------------------------------------------------------------------- // Calculate the case to proof //------------------------------------------------------------------------- float rz = me.GetMapObjectOrientation().rz; int wi = cast<int>(rz*180*100/Math.PI); // int rounded to 1/100 int ri = wi/(90*100); while (ri<0) ri=ri+4; while (ri>3) ri=ri-4; //------------------------------------------------------------------------- // Values of the edges (straight ölines) for the point coordinates //------------------------------------------------------------------------- float xAB = ValueXStraightline(P, W[0], W[1]); float yAB = ValueYStraightline(P, W[0], W[1]); float xBC = ValueXStraightline(P, W[1], W[2]); float yBC = ValueYStraightline(P, W[1], W[2]); float xCD = ValueXStraightline(P, W[2], W[3]); float yCD = ValueYStraightline(P, W[2], W[3]); float xAD = ValueXStraightline(P, W[0], W[3]); float yAD = ValueYStraightline(P, W[0], W[3]); //------------------------------------------------------------------------- // Calculating the resulting bool value //------------------------------------------------------------------------- switch(ri) { case 0: // 0° <= rz° < 90° if(yCD < P.y and P.y < yAB and xAD < P.x and P.x < xBC) return true; return false; case 1: // 90° <= rz° < 180° if(yAD < P.y and P.y < yBC and xAB < P.x and P.x < xCD) return true; return false; case 2: // 180° <= rz° < 270° if(yAB < P.y and P.y < yCD and xBC < P.x and P.x < xAD) return true; return false; case 3: // 270° <= rz° < 360° if(yBC < P.y and P.y < yAD and xCD < P.x and P.x < xAB) return true; return false; default: return false; } return false; } //--------------------------------------------------------------------------- };
File is located in dispatcher library.
acts_bridgecrain_globals.gs
include "acts_global_values.gs" include "acts_tools_script.gs" //--------------------------------------------------------------------------- // aCTS Bridgecrane V0.1 Central Script - acts_bridgecrane_globals.gs //----------------------------------------------------------------------------- // acts_bridgecrane <-- acts_bridgecrane_script // acts_bridgecrane_script <-- acts_bridgecrane_register // acts_bridgecrane_register <-- acts_bridgecrane_reachable // acts_bridgecrane_reachable <-- acts_bridgecrane_moving // acts_bridgecrane_moving <-- acts_bridgecrane_globals // X acts_bridgecrane_globals <-- acts_global_values // acts_global_values <-- MapObject //----------------------------------------------------------------------------- class acts_bridgecrane_globals isclass acts_global_values { //--------------------------------------------------------------------------- // AssetInstanceSoup { // X ObjectDataSoup { ... }, Only container, contstack, contcrane // X LocationSoup { ... }, Only container, contstack, contcrane // X OrientationSoup { ... }, Only container, contstack, contcrane // SkinDataSoup { ... }, Only container // ContentDataSoup { ... }, Only container // DispatcherDataSoup { ... } Only dispatcher // ContainerSoups { ... } Only dispatcher // ContstackSoups { ... } Only dispatcher // ContcraneSoups { ... } Only dispatcher // } //--------------------------------------------------------------------------- // ObjectDataSoup { goid GameObjectID, type string, // length string, height string, // stack goid, place int, Only container // active bool, action string }, // activ: true means the object sended a register message while session run // All objects were set false while initialising dispatcher and if // they stay false their entries will be deleted next initialising. // actions: ["APPENDED", "INSERTED", "UPDATED"]; //--------------------------------------------------------------------------- Soup ObjectDataSoup = Constructors.NewSoup(); //--------------------------------------------------------------------------- // LocationSoup { bbx int, bby int, // WorlCoordinate parameter // px float, py float, pz float } //------------------------------------------------------------------------- Soup LocationSoup = Constructors.NewSoup(); //------------------------------------------------------------------------- // OrientationSoup { rx float, ry float, rz float, // in rad // gx float, gy float, gz float } // in 1/10° //------------------------------------------------------------------------- Soup OrientationSoup = Constructors.NewSoup(); //------------------------------------------------------------------------- GameObjectID objectgoid = me.GetGameObjectID(); string objecttype = "CONTCRANE"; Library dispobj; GameObjectID dispgoid; //--------------------------------------------------------------------------- // Reach area values of the bridge crane will be loaded from this assets // config.txt file //--------------------------------------------------------------------------- int cranebase_reacharea_x; // 30000 in [mm] int cranebase_reacharea_y; // 100000 in [mm] int cranebase_reacharea_z; // 26000 in [mm] int cranebase_origin_inset_x; // 15000 in [mm] int cranebase_origin_inset_y; // 50000 in [mm] int cranebase_origin_inset_z; // 5000 in [mm] //--------------------------------------------------------------------------- int lift_zero_length = 1000; // 1000 in [mm] mandatory length for animation //--------------------------------------------------------------------------- int trolley_bottom_height; // in [mm] int lift_bottom_height; // in [mm] with lift z width as 1,000 [mm] int rotor_bottom_height; // in [mm] with rotor z width as 500 [mm] int gear_bottom_height; // in [mm] with gear z width as 500 [mm] //--------------------------------------------------------------------------- // TBD: And not proofed yet. Differntiate between maximum container count // for high cube and standard cube containers. //--------------------------------------------------------------------------- // For now the maximum count is calculated from reacharea z dimension minus // one hc height to ensure the movement of containers by the crane. Because // of possibly different base heights of the stacks inside the crane's // reacharea, there are some more different (possibly smaller) maximum // stackheights. // -------------------------------------------------------------------------- int max_container_count; // Construction based max stackable containers // -------------------------------------------------------------------------- }; //----------------------------------------------------------------------------- /* **************************************************************************** This is the scripted bridge crane object for an active container terminal system (aCTS). It is a kind of prototype of a bridge crane to let constructors know how the things are fitting and working for aCTS. ---------------------------------------------------------------------------- Some hints here too (see config description too): * The script logs dependin on the acts_debug variable (See acts.global_values.gs). So the script contains some overhead for testing informations. * Animations from Blender fbx runs from frame 1 ... n in Blender and fbx file. The import to Trainz will change this to frame 0 ... n-1, what is essential to know for precise transformations (moving and rotating) per animation frame. * The logical mesh hierarchy is as follows: cranebase--> -->cranebridge(py)-->trolley(px)-->lift(sz,pz)-->rotor(rz)-->gear(sx) * The cranes parts are imported to Trainz as own (animated) mesh objects with its respective origins at zero and its parented attachment points. All script calculations are based on this origin and the gaps to the attachment points for attaching the child meshes. The assets orientation is zero for x and y orientation. * The parent child hierarchy is realised within the mesh-table container. * The extensions values are in mm and define the reachable area of the cranes container gear. The dimensions x, y, z describe the cuboid length's, the gear may move and the insets x, y, z describes the location of the cranes origin within there. * The animations minimum frame 0 (resp. 1 in Blender) represents the locale relative minimal position (p = -inset) and the maximum frame (n = dimension) the maximal position p=dimension-inset. Example: dimension 80 inset 30 Trainz frames 0 10 20 30 40 50 60 70 80 Blender frames 1 11 21 31 41 51 61 71 81 Position -30 -20 -10 0 10 20 30 40 50 * The crane object (as well as the other object types) adjusts location to even mm and the orientation to 0.1 decimal degrees. * The movements of the cranes sub meshes will be realised with animation frame methods *MeshAnimation* from the MeshObject class in mashobject.gs ---------------------------------------------------------------------------- Technical parameters for calculating script values 1 [mm] and 0.1 [°] ---------------------------------------------------------------------------- Bridge [BPY: 100,001F: 140m] BF[1 .. 100001] [0mm(1)100,000mm] Trolley [TPX: 30,001F: 30m] BF[1 .. 30001] [-15,000mm(1)+15,000mm] Lift [LSZ: 25,001F: 1-26] BF[1 .. 25001] [1.000(0.001)26.000] [LPZ: 25,001F: 25m] BF[1 .. 25001] [+21,000mm(1)-5,000mm] Rotor [ROZ: 1,801F: 180°] BF[1 .. 1801] [-90.0°(0.1)+90.0°] Gear [GSY: 15,155F: 16.192m] BF[1 .. 16155] [1.000(0.001)16.154] ---------------------------------------------------------------------------- Containertype 10ft 20ft 40ft 45ft 53ft Gear scale scale/length 1.000m 2.991m 6.058m 12.192m 13.716m 16.154m ---------------------------------------------------------------------------- More informations are documented within the config.txt and script comments. ---------------------------------------------------------------------------- **************************************************************************** */
File is located in dispatcher library.