def __calcTrajectory(self, r0, v0, gravity, isOwnShoot, tracerCameraPos): ret = [] prevPos = r0 prevVelocity = v0 dt = 0.0 while True: dt += constants.SERVER_TICK_LENGTH checkPoints = computeProjectileTrajectory(prevPos, prevVelocity, gravity, constants.SERVER_TICK_LENGTH, constants.SHELL_TRAJECTORY_EPSILON_CLIENT) prevCheckPoint = prevPos for curCheckPoint in checkPoints: hitPoint = BigWorld.player().arena.collideWithSpaceBB(prevCheckPoint, curCheckPoint) if hitPoint is not None: ret.append((hitPoint, (hitPoint[0] - r0[0]) / v0[0], None)) return ret testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, prevCheckPoint, curCheckPoint, 128) if testRes is not None: hitPoint = testRes[0] distStatic = (hitPoint - prevCheckPoint).length destructibleDesc = None matKind = testRes[2] if matKind in xrange(DESTRUCTIBLE_MATKIND.NORMAL_MIN, DESTRUCTIBLE_MATKIND.NORMAL_MAX + 1): destructibleDesc = (testRes[5], testRes[4], matKind) distWater = -1.0 if isOwnShoot: rayDir = hitPoint - tracerCameraPos rayDir.normalise() rayEnd = hitPoint + rayDir * 1.5 testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, tracerCameraPos, rayEnd, 128) if testRes is not None: distStatic = (testRes[0] - tracerCameraPos).length distWater = BigWorld.wg_collideWater(tracerCameraPos, rayEnd) else: distWater = BigWorld.wg_collideWater(prevCheckPoint, curCheckPoint) if distWater < 0 or distWater > distStatic: ret.append((hitPoint, self.__getCollisionTime(r0, hitPoint, v0), destructibleDesc)) if destructibleDesc is None: return ret if distWater >= 0: srcPoint = tracerCameraPos if isOwnShoot else prevCheckPoint hitDirection = hitPoint - srcPoint hitDirection.normalise() hitPoint = srcPoint + hitDirection * distWater ret.append((hitPoint, self.__getCollisionTime(r0, hitPoint, v0), None)) return ret prevCheckPoint = curCheckPoint prevPos = r0 + v0.scale(dt) + gravity.scale(dt * dt * 0.5) prevVelocity = v0 + gravity.scale(dt) return
def __addExplosionEffect(self, position, proj, velocityDir): effectTypeStr = proj.get('effectMaterial', '') + 'Hit' p0 = Math.Vector3(position.x, 1000, position.z) p1 = Math.Vector3(position.x, -1000, position.z) waterDist = BigWorld.wg_collideWater(p0, p1, False) if waterDist > 0: waterY = p0.y - waterDist testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, p0, p1, 128) staticY = testRes.closestPoint.y if testRes is not None else waterY if staticY < waterY and position.y - waterY <= 0.1: shallowWaterDepth, rippleDiameter = proj['effectsDescr'][ 'waterParams'] if waterY - staticY < shallowWaterDepth: effectTypeStr = 'shallowWaterHit' else: effectTypeStr = 'deepWaterHit' position = Math.Vector3(position.x, waterY, position.z) self.__addWaterRipples(position, rippleDiameter, 5) keyPoints, effects, _ = proj['effectsDescr'][effectTypeStr] BigWorld.player().terrainEffects.addNew( position, effects, keyPoints, None, dir=velocityDir, start=position + velocityDir.scale(-1.0), end=position + velocityDir.scale(1.0), attackerID=proj['attackerID']) return
def __addExplosionEffect(self, position, effectsDescr, effectMaterial, velocityDir): effectTypeStr = effectMaterial + 'Hit' p0 = Math.Vector3(position.x, 1000, position.z) p1 = Math.Vector3(position.x, -1000, position.z) waterDist = BigWorld.wg_collideWater(p0, p1) if waterDist > 0: waterY = p0.y - waterDist testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, p0, p1, 128) staticY = testRes[0].y if testRes is not None else waterY if staticY < waterY and position.y - waterY <= 0.1: shallowWaterDepth, rippleDiameter = effectsDescr['waterParams'] if waterY - staticY < shallowWaterDepth: effectTypeStr = 'shallowWaterHit' else: effectTypeStr = 'deepWaterHit' position = Math.Vector3(position.x, waterY, position.z) self.__addWaterRipples(position, rippleDiameter, 5) stages, effects, _ = effectsDescr[effectTypeStr] BigWorld.player().terrainEffects.addNew( position, effects, stages, None, dir=velocityDir, start=position + velocityDir.scale(-1.0), end=position + velocityDir.scale(1.0)) return
def onStaticCollision(self, energy, point, normal): if self.__detachmentEffects is not None: surfaceMaterial = calcSurfaceMaterialNearPoint(point, normal, self.spaceID) effectIdx = surfaceMaterial.effectIdx groundEffect = True distToWater = BigWorld.wg_collideWater(self.position, surfaceMaterial.point) if distToWater != -1: vel = Math.Vector3(self.velocity).length if vel < _MIN_COLLISION_SPEED: groundEffect = False effectIdx = material_kinds.EFFECT_MATERIAL_INDEXES_BY_NAMES['water'] self.__detachmentEffects.notifyAboutCollision(energy, point, effectIdx, groundEffect, self.isUnderWater)
def __collideTerrainOnly(start, end): waterHeight = BigWorld.wg_collideWater(start, end, False) resultWater = None if waterHeight != -1: resultWater = start - Math.Vector3(0, waterHeight, 0) testResTerrain = BigWorld.wg_collideSegment(BigWorld.player().spaceID, start, end, 128, lambda matKind, collFlags, itemId, chunkId: collFlags & 8) result = testResTerrain[0] if testResTerrain is not None else None if resultWater is not None: distance = (result - start).length if distance - waterHeight < 0.2: return result return resultWater return result
def onStaticCollision(self, energy, point, normal): if self.__detachmentEffects is not None: surfaceMaterial = calcSurfaceMaterialNearPoint(point, normal, self.spaceID) effectIdx = surfaceMaterial.effectIdx groundEffect = True distToWater = BigWorld.wg_collideWater(self.position, surfaceMaterial.point) if distToWater != -1: vel = Math.Vector3(self.velocity).length if vel < _MIN_COLLISION_SPEED: groundEffect = False effectIdx = material_kinds.EFFECT_MATERIAL_INDEXES_BY_NAMES['water'] self.__detachmentEffects.notifyAboutCollision(energy, point, effectIdx, groundEffect, self.isUnderWater) return
def __collideTerrainOnly(start, end): waterHeight = BigWorld.wg_collideWater(start, end, False) resultWater = None if waterHeight != -1: resultWater = start - Math.Vector3(0, waterHeight, 0) testResTerrain = BigWorld.wg_collideSegment(BigWorld.player().spaceID, start, end, 128, 8) result = testResTerrain[0] if testResTerrain is not None else None if resultWater is not None: distance = (result - start).length if distance - waterHeight < 0.2: return result return resultWater else: return result
def __collideTerrainOnly(start, end): waterHeight = BigWorld.wg_collideWater(start, end, False) resultWater = None if waterHeight != -1: resultWater = start - Math.Vector3(0, waterHeight, 0) testResTerrain = BigWorld.wg_collideSegment(BigWorld.player().spaceID, start, end, 128, 8) result = testResTerrain.closestPoint if testResTerrain is not None else None if resultWater is not None: distance = (result - start).length if distance - waterHeight < 0.2: return result return resultWater else: return result
def __addExplosionEffect(self, position, effectsDescr, effectMaterial, velocityDir): effectTypeStr = effectMaterial + 'Hit' p0 = Math.Vector3(position.x, 1000, position.z) p1 = Math.Vector3(position.x, -1000, position.z) waterDist = BigWorld.wg_collideWater(p0, p1, False) if waterDist > 0: waterY = p0.y - waterDist testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, p0, p1, 128) staticY = testRes[0].y if testRes is not None else waterY if staticY < waterY and position.y - waterY <= 0.1: shallowWaterDepth, rippleDiameter = effectsDescr['waterParams'] if waterY - staticY < shallowWaterDepth: effectTypeStr = 'shallowWaterHit' else: effectTypeStr = 'deepWaterHit' position = Math.Vector3(position.x, waterY, position.z) self.__addWaterRipples(position, rippleDiameter, 5) keyPoints, effects, _ = effectsDescr[effectTypeStr] BigWorld.player().terrainEffects.addNew(position, effects, keyPoints, None, dir=velocityDir, start=position + velocityDir.scale(-1.0), end=position + velocityDir.scale(1.0))
def _doGroundWaveEffect(self, vehicle, groundWaveEff, gunModel, gunNode=None): node = gunModel.node('HP_gunFire' if gunNode is None else gunNode) gunMatr = Math.Matrix(node) gunPos = gunMatr.translation gunDir = gunMatr.applyVector((0, 0, 1)) upVec = Math.Matrix(vehicle.matrix).applyVector(Math.Vector3(0, 1, 0)) if upVec.y != 0: centerToGun = gunPos - vehicle.position centerToGunDist = centerToGun.length centerToGun.normalise() gunHeight = centerToGunDist * centerToGun.dot(upVec) / upVec.y gunPos.y -= gunHeight distanceToWater = BigWorld.wg_collideWater( gunPos, gunPos + Math.Vector3(0, 1, 0), False) if distanceToWater > -1: position = gunPos - Math.Vector3(0, distanceToWater, 0) matKind = material_kinds.getWaterMatKind() else: testRes = BigWorld.wg_collideSegment( BigWorld.player().spaceID, gunPos + Math.Vector3(0, 0.5, 0), gunPos - Math.Vector3(0, 1.5, 0), 128) if testRes is None: return position = testRes.closestPoint matKind = testRes.matKind BigWorld.player().terrainEffects.addNew( position, groundWaveEff.effectsList, groundWaveEff.keyPoints, None, dir=gunDir, surfaceMatKind=matKind, start=position + Math.Vector3(0, 0.5, 0), end=position - Math.Vector3(0, 0.5, 0), entity_id=vehicle.id) return
def __isPositionUnderwater(self, position): return BigWorld.wg_collideWater(position, position + Vector3(0, 1, 0), False) > -1.0
def __calcTrajectory(self, r0, v0, gravity, maxDistance, isOwnShoot, tracerCameraPos): ret = [] ownVehicle = BigWorld.entities.get(BigWorld.player().playerVehicleID) prevPos = r0 prevVelocity = v0 dt = 0.0 destrID = [] while True: dt += constants.SERVER_TICK_LENGTH checkPoints = computeProjectileTrajectory(prevPos, prevVelocity, gravity, constants.SERVER_TICK_LENGTH, constants.SHELL_TRAJECTORY_EPSILON_CLIENT) prevCheckPoint = prevPos prevDist0 = r0.distTo(prevCheckPoint) for curCheckPoint in checkPoints: curDist0 = r0.distTo(curCheckPoint) if curDist0 > maxDistance: curCheckPoint = prevCheckPoint + (curCheckPoint - prevCheckPoint) * ((maxDistance - prevDist0) / (curDist0 - prevDist0)) ret.append((curCheckPoint, (curCheckPoint[0] - r0[0]) / v0[0], None)) return ret hitPoint = BigWorld.player().arena.collideWithSpaceBB(prevCheckPoint, curCheckPoint) if hitPoint is not None: ret.append((hitPoint, (hitPoint[0] - r0[0]) / v0[0], None)) return ret testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, prevCheckPoint, curCheckPoint, 128, lambda matKind, collFlags, itemID, chunkID: (False if itemID in destrID else True)) if testRes is not None: hitPoint = testRes[0] distStatic = (hitPoint - prevCheckPoint).length destructibleDesc = None matKind = testRes[2] if matKind in xrange(DESTRUCTIBLE_MATKIND.NORMAL_MIN, DESTRUCTIBLE_MATKIND.NORMAL_MAX + 1): destructibleDesc = (testRes[5], testRes[4], matKind) destrID.append(testRes[4]) distWater = -1.0 useTracerCameraPos = False if isOwnShoot: rayDir = hitPoint - tracerCameraPos rayDir.normalise() if ownVehicle is not None: gunPos = ownVehicle.appearance.modelsDesc['gun']['model'].position if tracerCameraPos.y > gunPos.y: if (hitPoint - gunPos).length > 30.0: useTracerCameraPos = True if not useTracerCameraPos: distWater = BigWorld.wg_collideWater(prevCheckPoint, curCheckPoint, False) else: rayEnd = hitPoint + rayDir * 1.5 testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, tracerCameraPos, rayEnd, 128) if testRes is not None: distStatic = (testRes[0] - tracerCameraPos).length distWater = BigWorld.wg_collideWater(tracerCameraPos, rayEnd, False) else: distWater = BigWorld.wg_collideWater(prevCheckPoint, curCheckPoint, False) if distWater < 0 or distWater > distStatic: ret.append((hitPoint, self.__getCollisionTime(r0, hitPoint, v0), destructibleDesc)) if destructibleDesc is None: return ret prevCheckPoint = hitPoint continue if distWater >= 0: srcPoint = tracerCameraPos if useTracerCameraPos else prevCheckPoint hitDirection = hitPoint - srcPoint hitDirection.normalise() hitPoint = srcPoint + hitDirection * distWater ret.append((hitPoint, self.__getCollisionTime(r0, hitPoint, v0), None)) return ret prevCheckPoint = curCheckPoint prevDist0 = curDist0 prevPos = r0 + v0.scale(dt) + gravity.scale(dt * dt * 0.5) prevVelocity = v0 + gravity.scale(dt) return
def __calcTrajectory(self, r0, v0, gravity, isOwnShoot, tracerCameraPos): ret = [] prevPos = r0 prevVelocity = v0 dt = 0.0 while True: dt += constants.SERVER_TICK_LENGTH checkPoints = computeProjectileTrajectory( prevPos, prevVelocity, gravity, constants.SERVER_TICK_LENGTH, constants.SHELL_TRAJECTORY_EPSILON_CLIENT) prevCheckPoint = prevPos for curCheckPoint in checkPoints: hitPoint = BigWorld.player().arena.collideWithSpaceBB( prevCheckPoint, curCheckPoint) if hitPoint is not None: ret.append((hitPoint, (hitPoint[0] - r0[0]) / v0[0], None)) return ret testRes = BigWorld.wg_collideSegment(BigWorld.player().spaceID, prevCheckPoint, curCheckPoint, 128) if testRes is not None: hitPoint = testRes[0] distStatic = (hitPoint - prevCheckPoint).length destructibleDesc = None matKind = testRes[2] if matKind in xrange(DESTRUCTIBLE_MATKIND.NORMAL_MIN, DESTRUCTIBLE_MATKIND.NORMAL_MAX + 1): destructibleDesc = (testRes[5], testRes[4], matKind) distWater = -1.0 if isOwnShoot: rayDir = hitPoint - tracerCameraPos rayDir.normalise() rayEnd = hitPoint + rayDir * 1.5 testRes = BigWorld.wg_collideSegment( BigWorld.player().spaceID, tracerCameraPos, rayEnd, 128) if testRes is not None: distStatic = (testRes[0] - tracerCameraPos).length distWater = BigWorld.wg_collideWater( tracerCameraPos, rayEnd) else: distWater = BigWorld.wg_collideWater( prevCheckPoint, curCheckPoint) if distWater < 0 or distWater > distStatic: ret.append( (hitPoint, self.__getCollisionTime(r0, hitPoint, v0), destructibleDesc)) if destructibleDesc is None: return ret if distWater >= 0: srcPoint = tracerCameraPos if isOwnShoot else prevCheckPoint hitDirection = hitPoint - srcPoint hitDirection.normalise() hitPoint = srcPoint + hitDirection * distWater ret.append((hitPoint, self.__getCollisionTime(r0, hitPoint, v0), None)) return ret prevCheckPoint = curCheckPoint prevPos = r0 + v0.scale(dt) + gravity.scale(dt * dt * 0.5) prevVelocity = v0 + gravity.scale(dt) return