1
2	-- Crawler
3	-- This is the specialization for Crawlers
4	--
5	-- @author  Stefan Geiger
6	-- @date  30/11/08
7	--
8	-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
9	
10	Crawler = {};
11	
12	function Crawler.prerequisitesPresent(specializations)
13	    return SpecializationUtil.hasSpecialization(Drivable, specializations);
14	end;
15	
16	function Crawler:load(xmlFile)
17	    self.crawlers = {};
18	    Crawler.loadCrawlers(self, xmlFile, false);
19	end;
20	
21	function Crawler:loadCrawlers(xmlFile, isInitialized)
22	    local i = 0;
23	    while true do
24	        local key = string.format("vehicle.crawlers.crawler(%d)", i);
25	        if not hasXMLProperty(xmlFile, key) then
26	            break;
27	        end;
28	
29	        local indexBase = self.components;
30	        local crawler = {};
31	
32	        if not isInitialized then
33	            local filename = getXMLString(xmlFile, key .. "#filename");
34	            if filename ~= nil then
35	                crawler.filename = filename;
36	                crawlerIndex = Utils.getNoNil(getXMLString(xmlFile, key .. "#crawlerIndex"), "0|0");
37	                linkIndex = Utils.getNoNil(getXMLString(xmlFile, key .. "#linkIndex"), "0>");
38	                local i3dNode = Utils.loadSharedI3DFile(filename, self.baseDirectory, false, false, false);
39	                if i3dNode ~= 0 then
40	                    local loadedCrawler = Utils.indexToObject(i3dNode, crawlerIndex);
41	                    local linkNode = Utils.indexToObject(self.components, linkIndex);
42	                    link(linkNode, loadedCrawler);
43	                    indexBase = loadedCrawler;
44	                    delete(i3dNode);
45	                end;
46	            end;
47	
48	            crawler.node = Utils.indexToObject(indexBase, getXMLString(xmlFile, key.."#index"));
49	            crawler.speedRefNode = Utils.getNoNil(Utils.indexToObject(indexBase, getXMLString(xmlFile, key.."#speedRefNode")), node);
50	        else
51	            crawler = self.crawlers[i+1];
52	        end;
53	
54	        if crawler.node ~= nil then
55	            local speedRefWheel = getXMLInt(xmlFile, key.."#speedRefWheel");
56	            if speedRefWheel ~= nil and self.wheels[speedRefWheel] ~= nil then
57	                crawler.speedRefWheel = self.wheels[speedRefWheel];
58	            end;
59	            crawler.scrollSpeed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#scrollSpeed"), 1);
60	            crawler.shaderParameterName = Utils.getNoNil(getXMLString(xmlFile, key.."#shaderParameterName"), "scrollPosition");
61	            crawler.shaderParameterComponent = Utils.getNoNil(getXMLInt(xmlFile, key.."#shaderParameterComponent"), 1);
62	            crawler.scrollPosition = 0;
63	            crawler.scrollLength = Utils.getNoNil(getXMLFloat(xmlFile, key.."#scrollLength"), 1);
64	
65	            crawler.rotatingParts = Utils.getNoNil(crawler.rotatingParts, {});
66	            local j = 0;
67	            while true do
68	                local keyRotation = key..string.format(".rotatingPart(%d)", j);
69	                if not hasXMLProperty(xmlFile, keyRotation) then
70	                    break;
71	                end;
72	                local rotationPart = {};
73	                if not isInitialized then
74	                    rotationPart.node = Utils.indexToObject(indexBase, getXMLString(xmlFile, keyRotation.."#index"));
75	                else
76	                    rotationPart = crawler.rotatingParts[j+1];
77	                end;
78	                rotationPart.speedScale = getXMLFloat(xmlFile, keyRotation.."#speedScale");
79	                if rotationPart.speedScale == nil then
80	                    rotationPart.speedScale = 1.0 / Utils.getNoNil(getXMLFloat(xmlFile, keyRotation.."#radius"), 1);
81	                end;
82	                if rotationPart.node ~= nil and not isInitialized then
83	                    table.insert(crawler.rotatingParts, rotationPart);
84	                end;
85	                j = j + 1;
86	            end;
87	
88	            if not isInitialized then
89	                table.insert(self.crawlers, crawler);
90	            end;
91	        end;
92	        i = i + 1;
93	    end;
94	end;
95	
96	function Crawler:delete()
97	    for _, crawler in pairs(self.crawlers) do
98	        if crawler.filename ~= nil then
99	            Utils.releaseSharedI3DFile(crawler.filename, self.baseDirectory, true);
100	        end;
101	    end;
102	end;
103	
104	function Crawler:mouseEvent(posX, posY, isDown, isUp, button)
105	end;
106	
107	function Crawler:keyEvent(unicode, sym, modifier, isDown)
108	end;
109	
110	function Crawler:update(dt)
111	    if self:getIsActive() then
112	        for i, crawler in pairs(self.crawlers) do
113	            local movedDistance = 0;
114	
115	            if crawler.speedRefWheel ~= nil then
116	
117	                local newX, _, _ = getRotation(crawler.speedRefWheel.driveNode);
118	                if crawler.lastRotation == nil then
119	                    crawler.lastRotation = newX;
120	                end;
121	
122	                if newX - crawler.lastRotation < -math.pi then
123	                    crawler.lastRotation = crawler.lastRotation - 2*math.pi;
124	                elseif newX - crawler.lastRotation > math.pi then
125	                    crawler.lastRotation = crawler.lastRotation + 2*math.pi;
126	                end;
127	
128	                movedDistance = crawler.speedRefWheel.radius * (newX-crawler.lastRotation);
129	
130	                if i == 1 then
131	                    --print(" newX="..tostring(newX).." / "..tostring(crawler.lastRotation).." => "..tostring(movedDistance))
132	                end;
133	
134	                crawler.lastRotation = newX;
135	            else
136	                local newX, newY, newZ = getWorldTranslation(crawler.speedRefNode);
137	                if crawler.lastPosition == nil then
138	                    crawler.lastPosition = {newX, newY, newZ};
139	                end;
140	                local dx, dy, dz = worldDirectionToLocal(crawler.speedRefNode, newX-crawler.lastPosition[1], newY-crawler.lastPosition[2], newZ-crawler.lastPosition[3]);
141	                local movingDirection = 0;
142	                if dz > 0.0001 then
143	                    movingDirection = 1;
144	                elseif dz < -0.0001 then
145	                    movingDirection = -1;
146	                end;
147	                movedDistance = Utils.vector3Length(dx, dy, dz) * movingDirection;
148	                crawler.lastPosition[1] = newX;
149	                crawler.lastPosition[2] = newY;
150	                crawler.lastPosition[3] = newZ;
151	            end;
152	
153	            crawler.scrollPosition = (crawler.scrollPosition + movedDistance*crawler.scrollSpeed) % crawler.scrollLength;
154	            if crawler.shaderParameterComponent == 1 then
155	                setShaderParameter(crawler.node, crawler.shaderParameterName, crawler.scrollPosition,0,0,0, false);
156	            else
157	                setShaderParameter(crawler.node, crawler.shaderParameterName, 0,crawler.scrollPosition,0,0, false);
158	            end;
159	
160	            for _, rotatingPart in pairs(crawler.rotatingParts) do
161	                rotate(rotatingPart.node, rotatingPart.speedScale * movedDistance, 0, 0);
162	            end;
163	        end;
164	    end;
165	end;
166	
167	function Crawler:draw()
168	end;
169	
170	function Crawler:developmentReloadFromXML(xmlFile)
171	    Crawler.loadCrawlers(self, xmlFile, true);
172	end;